View Javadoc

1   package org.apache.maven.plugin.testing;
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.io.File;
23  import java.io.InputStream;
24  import java.util.Map;
25  
26  import org.apache.maven.execution.DefaultMavenExecutionRequest;
27  import org.apache.maven.execution.MavenExecutionRequest;
28  import org.apache.maven.execution.MavenSession;
29  import org.apache.maven.plugin.Mojo;
30  import org.apache.maven.plugin.MojoExecution;
31  import org.apache.maven.project.MavenProject;
32  import org.apache.maven.project.ProjectBuilder;
33  import org.apache.maven.project.ProjectBuildingRequest;
34  import org.codehaus.plexus.ContainerConfiguration;
35  import org.codehaus.plexus.PlexusContainer;
36  import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
37  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
38  import org.codehaus.plexus.configuration.PlexusConfiguration;
39  import org.codehaus.plexus.util.xml.Xpp3Dom;
40  import org.junit.Assert;
41  import org.junit.rules.TestRule;
42  import org.junit.runner.Description;
43  import org.junit.runners.model.Statement;
44  
45  /**
46   * {@link TestRule} for usage with Junit-4.10ff. This is just a wrapper for an embedded 
47   * {@link AbstractMojoTestCase}, so all <tt>protected</tt> methods of the TestCase are 
48   * exhibited as <tt>public</tt> in the rule. You may annotate single tests methods with 
49   * {@link WithoutMojo} to prevent the rule from firing.
50   *
51   * @author Mirko Friedenhagen
52   * @version $Id$
53   * @since 2.2
54   */
55  public class MojoRule
56      implements TestRule
57  {
58      private final AbstractMojoTestCase testCase;
59      
60      public MojoRule() 
61      {
62          this( new AbstractMojoTestCase() {} );
63      }
64  
65      public MojoRule(AbstractMojoTestCase testCase)
66      {
67          this.testCase = testCase;
68      }
69  
70      /**
71       * May be overridden in the implementation to do stuff <em>after</em> the embedded test case 
72       * is set up but <em>before</em> the current test is actually run.
73       *
74       * @throws Throwable
75       */
76      protected void before() throws Throwable
77      {
78          
79      }
80      
81      /**
82       * May be overridden in the implementation to do stuff after the current test was run.
83       */
84      protected void after() 
85      {
86          
87      }
88  
89      public InputStream getPublicDescriptorStream()
90          throws Exception
91      {
92          return testCase.getPublicDescriptorStream();
93      }
94  
95      public String getPluginDescriptorPath()
96      {
97          return testCase.getPluginDescriptorPath();
98      }
99  
100     public String getPluginDescriptorLocation()
101     {
102         return testCase.getPluginDescriptorLocation();
103     }
104 
105     public void setupContainer()
106     {
107         testCase.setupContainer();
108     }
109 
110     public ContainerConfiguration setupContainerConfiguration()
111     {
112         return testCase.setupContainerConfiguration();
113     }
114     
115     public PlexusContainer getContainer()
116     {
117         return testCase.getContainer();
118     }    
119     
120     /**
121      * Lookup the mojo leveraging the subproject pom
122      *
123      * @param goal
124      * @param pluginPom
125      * @return a Mojo instance
126      * @throws Exception
127      */
128     public Mojo lookupMojo( String goal, String pluginPom )
129         throws Exception
130     {
131         return testCase.lookupMojo( goal, pluginPom );
132     }
133 
134     /**
135      * Lookup an empty mojo
136      *
137      * @param goal
138      * @param pluginPom
139      * @return a Mojo instance
140      * @throws Exception
141      */
142     public Mojo lookupEmptyMojo( String goal, String pluginPom )
143         throws Exception
144     {
145         return testCase.lookupEmptyMojo( goal, new File( pluginPom ) );
146     }
147 
148     /**
149      * Lookup the mojo leveraging the actual subprojects pom
150      *
151      * @param goal
152      * @param pom
153      * @return a Mojo instance
154      * @throws Exception
155      */
156     public Mojo lookupMojo( String goal, File pom )
157         throws Exception
158     {
159         return testCase.lookupMojo( goal, pom );
160     }
161 
162     /**
163      * Lookup the mojo leveraging the actual subprojects pom
164      *
165      * @param goal
166      * @param pom
167      * @return a Mojo instance
168      * @throws Exception
169      */
170     public Mojo lookupEmptyMojo( String goal, File pom )
171         throws Exception
172     {
173         return testCase.lookupEmptyMojo( goal, pom );
174     }
175 
176     public Mojo lookupMojo( String groupId, String artifactId, String version, String goal,
177                                PlexusConfiguration pluginConfiguration )
178         throws Exception
179     {
180         return testCase.lookupMojo( groupId, artifactId, version, goal, pluginConfiguration );
181     }
182 
183     public Mojo lookupConfiguredMojo( MavenProject project, String goal )
184         throws Exception
185     {
186         return testCase.lookupConfiguredMojo( project, goal );
187     }
188 
189     public Mojo lookupConfiguredMojo( MavenSession session, MojoExecution execution )
190         throws Exception, ComponentConfigurationException
191     {
192         return testCase.lookupConfiguredMojo( session, execution );
193     }
194 
195     public MavenSession newMavenSession( MavenProject project )
196     {
197         return testCase.newMavenSession( project );
198     }
199 
200     public MojoExecution newMojoExecution( String goal )
201     {
202         return testCase.newMojoExecution( goal );
203     }
204 
205     public PlexusConfiguration extractPluginConfiguration( String artifactId, File pom )
206         throws Exception
207     {
208         return testCase.extractPluginConfiguration( artifactId, pom );
209     }
210 
211     public PlexusConfiguration extractPluginConfiguration( String artifactId, Xpp3Dom pomDom )
212         throws Exception
213     {
214         return testCase.extractPluginConfiguration( artifactId, pomDom );
215     }
216 
217     public Mojo configureMojo( Mojo mojo, String artifactId, File pom )
218         throws Exception
219     {
220         return testCase.configureMojo( mojo, artifactId, pom );
221     }
222 
223     public Mojo configureMojo( Mojo mojo, PlexusConfiguration pluginConfiguration )
224         throws Exception
225     {
226         return testCase.configureMojo( mojo, pluginConfiguration );
227     }
228 
229     /**
230      * Convenience method to obtain the value of a variable on a mojo that might not have a getter.
231      *
232      * NOTE: the caller is responsible for casting to to what the desired type is.
233      *
234      * @param object
235      * @param variable
236      * @return object value of variable
237      * @throws IllegalArgumentException
238      */
239     public Object getVariableValueFromObject( Object object, String variable )
240         throws IllegalAccessException
241     {
242         return testCase.getVariableValueFromObject( object, variable );
243     }
244 
245     /**
246      * Convenience method to obtain all variables and values from the mojo (including its superclasses)
247      *
248      * Note: the values in the map are of type Object so the caller is responsible for casting to desired types.
249      *
250      * @param object
251      * @return map of variable names and values
252      */
253     public Map<String, Object> getVariablesAndValuesFromObject( Object object )
254         throws IllegalAccessException
255     {
256         return testCase.getVariablesAndValuesFromObject( object );
257     }
258 
259     /**
260      * Convenience method to obtain all variables and values from the mojo (including its superclasses)
261      *
262      * Note: the values in the map are of type Object so the caller is responsible for casting to desired types.
263      *
264      * @param clazz
265      * @param object
266      * @return map of variable names and values
267      */
268     public Map<String, Object> getVariablesAndValuesFromObject( Class<?> clazz, Object object )
269         throws IllegalAccessException
270     {
271         return testCase.getVariablesAndValuesFromObject( clazz, object );
272     }
273 
274     /**
275      * Convenience method to set values to variables in objects that don't have setters
276      *
277      * @param object
278      * @param variable
279      * @param value
280      * @throws IllegalAccessException
281      */
282     public void setVariableValueToObject( Object object, String variable, Object value )
283         throws IllegalAccessException
284     {
285         testCase.setVariableValueToObject( object, variable, value );
286     }
287 
288     @Override
289     public Statement apply(final Statement base, Description description) {
290         if (description.getAnnotation(WithoutMojo.class) != null) // skip.
291         {
292             return base;
293         }
294         return new Statement() 
295         {
296             @Override
297             public void evaluate() throws Throwable 
298             {
299                 testCase.setUp();
300                 before();
301                 try 
302                 {
303                     base.evaluate();
304                 } 
305                 finally 
306                 {
307                     after();
308                 }
309             }            
310         };       
311     }
312 
313     /**
314      * @since 3.1.0
315      */
316     public MavenProject readMavenProject( File basedir )
317         throws Exception
318     {
319         File pom = new File( basedir, "pom.xml" );
320         MavenExecutionRequest request = new DefaultMavenExecutionRequest();
321         request.setBaseDirectory( basedir );
322         ProjectBuildingRequest configuration = request.getProjectBuildingRequest();
323         MavenProject project = lookup( ProjectBuilder.class ).build( pom, configuration ).getProject();
324         Assert.assertNotNull( project );
325         return project;
326     }
327 
328     /**
329      * @since 3.1.0
330      */
331     public void executeMojo( File basedir, String goal )
332         throws Exception
333     {
334         lookupConfiguredMojo( basedir, goal ).execute();
335     }
336 
337     /**
338      * @since 3.1.0
339      */
340     public Mojo lookupConfiguredMojo( File basedir, String goal )
341         throws Exception, ComponentConfigurationException
342     {
343         MavenProject project = readMavenProject( basedir );
344         MavenSession session = newMavenSession( project );
345         MojoExecution execution = newMojoExecution( goal );
346         return lookupConfiguredMojo( session, execution );
347     }
348 
349     /**
350      * @since 3.1.0
351      */
352     public final <T> T lookup( final Class<T> role )
353         throws ComponentLookupException
354     {
355         return getContainer().lookup( role );
356     }
357 
358 }