001package org.apache.maven.model.inheritance;
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
022import org.apache.maven.model.Model;
023import org.apache.maven.model.building.SimpleProblemCollector;
024import org.apache.maven.model.io.ModelParseException;
025import org.apache.maven.model.io.ModelReader;
026import org.apache.maven.model.io.ModelWriter;
027import org.codehaus.plexus.PlexusTestCase;
028import org.custommonkey.xmlunit.XMLAssert;
029import org.custommonkey.xmlunit.XMLUnit;
030
031import junit.framework.AssertionFailedError;
032
033import java.io.File;
034import java.io.FileInputStream;
035import java.io.IOException;
036import java.io.InputStreamReader;
037import java.io.Reader;
038
039/**
040 * @author Hervé Boutemy
041 */
042public class DefaultInheritanceAssemblerTest
043    extends PlexusTestCase
044{
045    private ModelReader reader;
046
047    private ModelWriter writer;
048
049    private InheritanceAssembler assembler;
050
051    @Override
052    protected void setUp()
053        throws Exception
054    {
055        super.setUp();
056
057        reader = lookup( ModelReader.class );
058        writer = lookup( ModelWriter.class );
059        assembler = lookup( InheritanceAssembler.class );
060    }
061
062    private File getPom( String name )
063    {
064        return getTestFile( "src/test/resources/poms/inheritance/" + name + ".xml" );
065    }
066
067    private Model getModel( String name )
068        throws ModelParseException, IOException
069    {
070        return reader.read( getPom( name ), null );
071    }
072
073    public void testPluginConfiguration()
074        throws Exception
075    {
076        testInheritance( "plugin-configuration" );
077    }
078
079    /**
080     * Check most classical urls inheritance: directory structure where parent POM in parent directory
081     * and child directory == artifatId
082     * @throws Exception
083     */
084    public void testUrls()
085        throws Exception
086    {
087        testInheritance( "urls" );
088    }
089
090    /**
091     * Flat directory structure: parent & child POMs in sibling directories, child directory == artifactId.
092     * @throws Exception
093     */
094    public void testFlatUrls()
095        throws Exception
096    {
097        testInheritance( "flat-urls" );
098    }
099
100    /**
101     * Tricky case: flat directory structure, but child directory != artifactId.
102     * Model interpolation does not give same result when calculated from build or from repo...
103     * This is why MNG-5000 fix in code is marked as bad practice (uses file names)
104     * @throws Exception
105     */
106    public void testFlatTrickyUrls()
107        throws Exception
108    {
109        // parent references child with artifactId (which is not directory name)
110        // then relative path calculation will fail during build from disk but success when calculated from repo
111        try
112        {
113            // build from disk expected to fail
114            testInheritance( "tricky-flat-artifactId-urls", false );
115            fail( "should have failed since module reference == artifactId != directory name" );
116        }
117        catch ( AssertionFailedError afe )
118        {
119            // expected failure: wrong relative path calculation
120            assertTrue( afe.getMessage().contains( "http://www.apache.org/path/to/parent/child-artifact-id/" ) );
121        }
122        // but ok from repo: local disk is ignored
123        testInheritance( "tricky-flat-artifactId-urls", true );
124
125        // parent references child with directory name (which is not artifact id)
126        // then relative path calculation will success during build from disk but failwhen calculated from repo
127        testInheritance( "tricky-flat-directory-urls", false );
128        try
129        {
130            testInheritance( "tricky-flat-directory-urls", true );
131            fail( "should have failed since module reference == directory name != artifactId" );
132        }
133        catch ( AssertionFailedError afe )
134        {
135            // expected failure
136            assertTrue( afe.getMessage().contains( "http://www.apache.org/path/to/parent/child-artifact-id/" ) );
137        }
138    }
139
140    public void testWithEmptyUrl() 
141        throws Exception
142    {
143                testInheritance( "empty-urls", false );
144    }
145    
146    public void testInheritance( String baseName )
147        throws Exception
148    {
149        testInheritance( baseName, false );
150        testInheritance( baseName, true );
151    }
152
153    public void testInheritance( String baseName, boolean fromRepo )
154        throws Exception
155    {
156        Model parent = getModel( baseName + "-parent" );
157
158        Model child = getModel( baseName + "-child" );
159
160        if ( fromRepo )
161        {
162            // when model is read from repo, a stream is used, then pomFile == null
163            // (has consequences in inheritance algorithm since getProjectDirectory() returns null)
164            parent.setPomFile( null );
165            child.setPomFile( null );
166        }
167
168        SimpleProblemCollector problems = new SimpleProblemCollector();
169
170        assembler.assembleModelInheritance( child, parent, null, problems );
171
172        // write baseName + "-actual"
173        File actual = getTestFile( "target/test-classes/poms/inheritance/" + baseName
174            + ( fromRepo ? "-build" : "-repo" ) + "-actual.xml" );
175        writer.write( actual, null, child );
176
177        // check with getPom( baseName + "-expected" )
178        File expected = getPom( baseName + "-expected" );
179        try ( Reader control = new InputStreamReader( new FileInputStream( expected ), "UTF-8" );
180              Reader test = new InputStreamReader( new FileInputStream( actual ), "UTF-8" ) )
181        {
182            XMLUnit.setIgnoreComments( true );
183            XMLUnit.setIgnoreWhitespace( true );
184            XMLAssert.assertXMLEqual( control, test );
185        }
186    }    
187}