View Javadoc
1   package com.simpligility.maven.plugins.android;
2   
3   import static org.easymock.EasyMock.*;
4   
5   import java.io.File;
6   
7   import org.apache.commons.io.FileUtils;
8   import org.apache.commons.io.FilenameUtils;
9   import org.apache.maven.execution.MavenSession;
10  import org.apache.maven.plugin.DebugConfigurationListener;
11  import org.apache.maven.plugin.MojoExecution;
12  import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
13  import org.apache.maven.plugin.descriptor.MojoDescriptor;
14  import org.apache.maven.plugin.testing.AbstractMojoTestCase;
15  import org.apache.maven.project.MavenProject;
16  import org.apache.maven.project.path.DefaultPathTranslator;
17  import org.apache.maven.project.path.PathTranslator;
18  import org.codehaus.plexus.component.configurator.ComponentConfigurator;
19  import org.codehaus.plexus.component.configurator.ConfigurationListener;
20  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
21  import org.codehaus.plexus.configuration.PlexusConfiguration;
22  import org.codehaus.plexus.logging.Logger;
23  import org.codehaus.plexus.logging.console.ConsoleLogger;
24  import org.junit.Assert;
25  import org.powermock.reflect.Whitebox;
26  
27  import com.simpligility.maven.plugins.android.AbstractAndroidMojo;
28  import com.simpligility.maven.plugins.android.standalonemojos.ManifestUpdateMojo;
29  import com.simpligility.maven.plugins.android.standalonemojos.MojoProjectStub;
30  
31  public abstract class AbstractAndroidMojoTestCase<T extends AbstractAndroidMojo> extends AbstractMojoTestCase {
32  
33      protected MavenSession session;
34      protected MojoExecution execution;
35  
36  
37      /**
38       * The Goal Name of the Plugin being tested.
39       * <p>
40       * Used to look for <code>&lt;configuration&gt;</code> section in the <code>plugin-config.xml</code> 
41       * that will be used to configure the mojo from.
42       * 
43       * @return the string name of the goal. (eg "version-update", "dex", etc...)
44       */
45      public abstract String getPluginGoalName();
46  
47      /**
48       * Copy the project specified into a temporary testing directory. Create the {@link MavenProject} and
49       * {@link ManifestUpdateMojo}, configure it from the <code>plugin-config.xml</code> and return the created Mojo.
50       * <p>
51       * Note: only configuration entries supplied in the plugin-config.xml are presently configured in the mojo returned.
52       * That means and 'default-value' settings are not automatically injected by this testing framework (or plexus
53       * underneath that is suppling this functionality)
54       * 
55       * @param resourceProject
56       *            the name of the goal to look for in the <code>plugin-config.xml</code> that the configuration will be
57       *            pulled from.
58       * @param resourceProject
59       *            the resourceProject path (in src/test/resources) to find the example/test project.
60       * @return the created mojo (unexecuted)
61       * @throws Exception
62       *             if there was a problem creating the mojo.
63       */
64      protected T createMojo(String resourceProject) throws Exception {
65          // Establish test details project example
66          String testResourcePath = "src/test/resources/" + resourceProject;
67          testResourcePath = FilenameUtils.separatorsToSystem(testResourcePath);
68          File exampleDir = new File(getBasedir(), testResourcePath);
69          Assert.assertTrue("Path should exist: " + exampleDir, exampleDir.exists());
70  
71          // Establish the temporary testing directory.
72          String testingPath = "target/tests/" + this.getClass().getSimpleName() + "." + getName();
73          testingPath = FilenameUtils.separatorsToSystem(testingPath);
74          File testingDir = new File(getBasedir(), testingPath);
75  
76          if (testingDir.exists()) {
77              FileUtils.cleanDirectory(testingDir);
78          } else {
79              Assert.assertTrue("Could not create directory: " + testingDir, testingDir.mkdirs());
80          }
81  
82          // Copy project example into temporary testing directory
83          // to avoid messing up the good source copy, as mojo can change
84          // the AndroidManifest.xml file.
85          FileUtils.copyDirectory(exampleDir, testingDir);
86  
87          // Prepare MavenProject
88          final MavenProject project = new MojoProjectStub(testingDir);
89  
90          // Setup Mojo
91          PlexusConfiguration config = extractPluginConfiguration("android-maven-plugin", project.getFile());
92          @SuppressWarnings("unchecked")
93          final T mojo = (T) lookupMojo(getPluginGoalName(), project.getFile());
94  
95          // Inject project itself
96          setVariableValueToObject(mojo, "project", project);
97  
98          // Configure the rest of the pieces via the PluginParameterExpressionEvaluator
99          //  - used for ${plugin.*}
100         MojoDescriptor mojoDesc = new MojoDescriptor();
101         // - used for error messages in PluginParameterExpressionEvaluator
102         mojoDesc.setGoal(getPluginGoalName());
103         MojoExecution mojoExec = new MojoExecution(mojoDesc);
104         // - Only needed if we start to use expressions like ${settings.*}, ${localRepository}, ${reactorProjects}
105         // MavenSession context = null; // Messy to declare, would rather avoid using it.
106         // - Used for ${basedir} relative paths
107         PathTranslator pathTranslator = new DefaultPathTranslator();
108         // - Declared to prevent NPE from logging events in maven core
109         Logger logger = new ConsoleLogger(Logger.LEVEL_DEBUG, mojo.getClass().getName());
110 
111         MavenSession context = createNiceMock( MavenSession.class );
112 
113         expect( context.getExecutionProperties() ).andReturn( project.getProperties() );
114         expect( context.getCurrentProject() ).andReturn( project );
115         replay( context );
116 
117         // Declare evalator that maven itself uses.
118         ExpressionEvaluator evaluator = new PluginParameterExpressionEvaluator(
119             context, mojoExec, pathTranslator, logger, project, project.getProperties() );
120         // Lookup plexus configuration component
121         ComponentConfigurator configurator = (ComponentConfigurator) lookup(ComponentConfigurator.ROLE,"basic");
122         // Configure mojo using above
123         ConfigurationListener listener = new DebugConfigurationListener( logger );
124         configurator.configureComponent( mojo, config, evaluator, getContainer().getContainerRealm(), listener );
125 
126         this.session = context;
127         this.execution = mojoExec;
128 
129         Whitebox.setInternalState( mojo, "session", this.session );
130         Whitebox.setInternalState( mojo, "execution", this.execution );
131 
132         return mojo;
133     }
134 
135 
136 
137     /**
138      * Get the project directory used for this mojo.
139      * 
140      * @param mojo the mojo to query.
141      * @return the project directory.
142      * @throws IllegalAccessException if unable to get the project directory.
143      */
144     public File getProjectDir(AbstractAndroidMojo mojo) throws IllegalAccessException {
145         MavenProject project = (MavenProject) getVariableValueFromObject(mojo, "project");
146         return project.getFile().getParentFile();
147     }
148 }