package com.simpligility.maven.plugins.android.standalonemojos; import com.simpligility.maven.plugins.android.AbstractAndroidMojoTestCase; import com.simpligility.maven.plugins.android.CommandExecutor; import com.simpligility.maven.plugins.android.common.AndroidExtension; import com.simpligility.maven.plugins.android.config.ConfigHandler; import com.simpligility.maven.plugins.android.standalonemojos.ZipalignMojo; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.codehaus.plexus.util.FileUtils; import org.easymock.Capture; import org.easymock.EasyMock; import org.junit.Ignore; import org.junit.runner.RunWith; import org.powermock.api.easymock.PowerMock; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.reflect.Whitebox; import java.io.File; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; /** * User: Eugen */ @Ignore("This test has to be migrated to be an IntegrationTest using AbstractAndroidMojoIntegrationTest") @RunWith ( PowerMockRunner.class ) @PrepareForTest ( { CommandExecutor.Factory.class, FileUtils.class, ZipalignMojo.class } ) public class ZipalignMojoTest extends AbstractAndroidMojoTestCase<ZipalignMojo> { @Override public String getPluginGoalName () { return "zipalign"; } /** * Tests all options, checks if their default values are correct. * * @throws Exception */ public void testDefaultConfig () throws Exception { ZipalignMojo mojo = createMojo( "zipalign-config-project0" ); final ConfigHandler cfh = new ConfigHandler( mojo, this.session, this.execution ); cfh.parseConfiguration(); Boolean skip = Whitebox.getInternalState( mojo, "parsedSkip" ); assertTrue( "zipalign 'skip' parameter should be true", skip ); Boolean verbose = Whitebox.getInternalState( mojo, "parsedVerbose" ); assertFalse( "zipalign 'verbose' parameter should be false", verbose ); MavenProject project = Whitebox.getInternalState( mojo, "project" ); String inputApk = Whitebox.getInternalState( mojo, "parsedInputApk" ); File inputApkFile = new File( project.getBuild().getDirectory(), project.getBuild().getFinalName() + ".apk" ); assertEquals( "zipalign 'inputApk' parameter should be equal", inputApkFile.getAbsolutePath(), inputApk ); String outputApk = Whitebox.getInternalState( mojo, "parsedOutputApk" ); File outputApkFile = new File( project.getBuild().getDirectory(), project.getBuild().getFinalName() + "-aligned.apk" ); assertEquals( "zipalign 'outputApk' parameter should be equal", outputApkFile.getAbsolutePath(), outputApk ); } /** * Tests all parameters parsing * * Probably not needed since it is like testing maven itself * * @throws Exception */ public void testConfigParse () throws Exception { ZipalignMojo mojo = createMojo( "zipalign-config-project1" ); final ConfigHandler cfh = new ConfigHandler( mojo, this.session, this.execution ); cfh.parseConfiguration(); Boolean skip = Whitebox.getInternalState( mojo, "parsedSkip" ); assertFalse( "zipalign 'skip' parameter should be false", skip ); Boolean verbose = Whitebox.getInternalState( mojo, "parsedVerbose" ); assertTrue( "zipalign 'verbose' parameter should be true", verbose ); String inputApk = Whitebox.getInternalState( mojo, "parsedInputApk" ); assertEquals( "zipalign 'inputApk' parameter should be equal", "app.apk", inputApk ); String outputApk = Whitebox.getInternalState( mojo, "parsedOutputApk" ); assertEquals( "zipalign 'outputApk' parameter should be equal", "app-updated.apk", outputApk ); } /** * Tests run of zipalign with correct parameters as well adding aligned file to artifacts * * @throws Exception */ public void testDefaultRun () throws Exception { ZipalignMojo mojo = createMojo( "zipalign-config-project3" ); MavenProject project = Whitebox.getInternalState( mojo, "project" ); project.setPackaging( AndroidExtension.APK ); MavenProjectHelper projectHelper = EasyMock.createNiceMock( MavenProjectHelper.class ); Capture<File> capturedParameter = new Capture<File>(); projectHelper.attachArtifact( EasyMock.eq( project ), EasyMock.eq( AndroidExtension.APK ), EasyMock.eq( "aligned" ), EasyMock.capture( capturedParameter ) ); Whitebox.setInternalState( mojo, "projectHelper", projectHelper ); final CommandExecutor mockExecutor = PowerMock.createMock( CommandExecutor.class ); PowerMock.replace( CommandExecutor.Factory.class.getDeclaredMethod( "createDefaultCommmandExecutor" ) ).with( new InvocationHandler() { @Override public Object invoke ( Object proxy, Method method, Object[] args ) throws Throwable { return mockExecutor; } } ); Capture<List<String>> capturedFile = new Capture<List<String>>(); mockExecutor.setLogger( EasyMock.anyObject( Log.class ) ); mockExecutor.setCaptureStdOut( EasyMock.anyBoolean() ); mockExecutor.executeCommand( EasyMock.anyObject( String.class ), EasyMock.capture( capturedFile ) ); PowerMock.mockStatic( FileUtils.class ); EasyMock.expect( FileUtils.fileExists( "app-updated.apk" ) ).andReturn( true ); EasyMock.replay( projectHelper ); PowerMock.replay( mockExecutor ); PowerMock.replay( FileUtils.class ); mojo.execute(); PowerMock.verify( mockExecutor ); List<String> parameters = capturedFile.getValue(); List<String> parametersExpected = new ArrayList<String>(); parametersExpected.add( "-v" ); parametersExpected.add( "-f" ); parametersExpected.add( "4" ); parametersExpected.add( "app.apk" ); parametersExpected.add( "app-updated.apk" ); assertEquals( "Zipalign arguments aren't as expected", parametersExpected, parameters ); PowerMock.verify( projectHelper ); assertEquals( "File should be same as expected", new File( "app-updated.apk" ), capturedParameter.getValue() ); // verify that all method were invoked PowerMock.verify( FileUtils.class ); } /** * Tests run of zipalign with correct parameters * * @throws Exception */ public void testRunWhenInputApkIsSameAsOutput () throws Exception { ZipalignMojo mojo = createMojo( "zipalign-config-project2" ); MavenProject project = Whitebox.getInternalState( mojo, "project" ); project.setPackaging( AndroidExtension.APK ); MavenProjectHelper projectHelper = EasyMock.createNiceMock( MavenProjectHelper.class ); Whitebox.setInternalState( mojo, "projectHelper", projectHelper ); final CommandExecutor mockExecutor = PowerMock.createMock( CommandExecutor.class ); PowerMock.replace( CommandExecutor.Factory.class.getDeclaredMethod( "createDefaultCommmandExecutor" ) ).with( new InvocationHandler() { @Override public Object invoke ( Object proxy, Method method, Object[] args ) throws Throwable { return mockExecutor; } } ); Capture<List<String>> capturedFile = new Capture<List<String>>(); mockExecutor.setLogger( EasyMock.anyObject( Log.class ) ); mockExecutor.setCaptureStdOut( EasyMock.anyBoolean() ); mockExecutor.executeCommand( EasyMock.anyObject( String.class ), EasyMock.capture( capturedFile ) ); PowerMock.mockStatic( FileUtils.class ); EasyMock.expect( FileUtils.fileExists( "app-aligned-temp.apk" ) ).andReturn( true ); FileUtils.rename( new File( "app-aligned-temp.apk" ) , new File( "app.apk" ) ); EasyMock.expectLastCall(); PowerMock.replay( projectHelper ); PowerMock.replay( mockExecutor ); PowerMock.replay( FileUtils.class ); mojo.execute(); PowerMock.verify( mockExecutor ); List<String> parameters = capturedFile.getValue(); List<String> parametersExpected = new ArrayList<String>(); parametersExpected.add( "-v" ); parametersExpected.add( "-f" ); parametersExpected.add( "4" ); parametersExpected.add( "app.apk" ); parametersExpected.add( "app-aligned-temp.apk" ); assertEquals( "Zipalign arguments aren't as expected", parametersExpected, parameters ); // no invocations to attach artifact PowerMock.verify( projectHelper ); // verify that all method were invoked PowerMock.verify( FileUtils.class ); } }