/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tools.idea.wizard;
import com.android.SdkConstants;
import com.android.tools.idea.templates.AndroidGradleTestCase;
import com.android.tools.idea.templates.Template;
import com.android.tools.idea.templates.TemplateUtils;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import java.io.File;
import static com.android.tools.idea.templates.TemplateMetadata.*;
import static com.android.tools.idea.wizard.NewProjectWizardState.*;
import static org.mockito.Mockito.*;
/**
* Tests for the New Project Wizard.
*/
public class NewProjectWizardTest extends AndroidGradleTestCase {
NewProjectWizard myWizard;
NewProjectWizardState myWizardState;
private static final String MODULE_NAME = "thisisamodulename";
@Override
protected boolean requireRecentSdk() {
// Need valid SDK templates
return true;
}
@Override
public void setUp() throws Exception {
super.setUp();
myWizard = new NewProjectWizard();
myWizardState = myWizard.myWizardState;
}
@Override
public void tearDown() throws Exception {
Disposer.dispose(myWizard.getDisposable());
super.tearDown();
}
public void testInit() throws Exception {
// After construction
assertNotNull(myWizardState);
assertTrue(myWizardState.hasAttr(ATTR_GRADLE_VERSION));
assertTrue(myWizardState.hasAttr(ATTR_GRADLE_PLUGIN_VERSION));
assertTrue(myWizardState.hasAttr(ATTR_MIN_API));
assertTrue(myWizardState.get(ATTR_MIN_API) instanceof String);
assertTrue(myWizardState.hasAttr(ATTR_BUILD_API));
assertTrue(myWizardState.get(ATTR_BUILD_API) instanceof Integer);
assertTrue(myWizardState.hasAttr(ATTR_BUILD_API_STRING));
assertTrue(myWizardState.get(ATTR_BUILD_API_STRING) instanceof String);
assertTrue(myWizardState.hasAttr(ATTR_MIN_API_LEVEL));
assertTrue(myWizardState.get(ATTR_MIN_API_LEVEL) instanceof Integer);
assertTrue(myWizardState.hasAttr(ATTR_TARGET_API));
assertTrue(myWizardState.get(ATTR_TARGET_API) instanceof Integer);
assertTrue(myWizardState.hasAttr(ATTR_TARGET_API_STRING));
assertTrue(myWizardState.get(ATTR_TARGET_API_STRING) instanceof String);
assertEquals(4, myWizard.getStepCount());
assertNotNull(myWizard.myAssetSetStep);
assertNotNull(myWizard.myChooseActivityStep);
assertNotNull(myWizard.myActivityParameterStep);
assertTrue(myWizard.myInitializationComplete);
}
public void testUpdate() throws Exception {
myWizardState.put(ATTR_CREATE_ICONS, true);
myWizardState.put(ATTR_CREATE_ACTIVITY, true);
myWizard.update();
assertVisibilityMatchesParameter(myWizard.myAssetSetStep, ATTR_CREATE_ICONS);
assertVisibilityMatchesParameter(myWizard.myChooseActivityStep, ATTR_CREATE_ACTIVITY);
assertVisibilityMatchesParameter(myWizard.myActivityParameterStep, ATTR_CREATE_ACTIVITY);
myWizardState.put(ATTR_CREATE_ICONS, false);
myWizardState.put(ATTR_CREATE_ACTIVITY, false);
myWizard.update();
assertVisibilityMatchesParameter(myWizard.myAssetSetStep, ATTR_CREATE_ICONS);
assertVisibilityMatchesParameter(myWizard.myChooseActivityStep, ATTR_CREATE_ACTIVITY);
assertVisibilityMatchesParameter(myWizard.myActivityParameterStep, ATTR_CREATE_ACTIVITY);
}
private void assertVisibilityMatchesParameter(TemplateWizardStep step, String paramName) {
assertEquals(myWizardState.getBoolean(paramName), step.isStepVisible());
}
/**
* Sets up standard project/module creation
*/
private void setUpStandardProjectCreation() throws Exception {
File baseDir = new File(getProject().getBasePath());
myWizardState.put(FormFactorUtils.ATTR_MODULE_NAME, MODULE_NAME);
myWizardState.put(ATTR_PROJECT_LOCATION, baseDir.getPath());
String projectName = "ThisIsAProjectName";
myWizardState.put(ATTR_APP_TITLE, projectName);
myWizardState.put(ATTR_PACKAGE_NAME, "com.test.package");
}
/**
* Returns the module directory.
*/
private File runCommonCreateProjectTest() throws Exception {
File baseDir = new File(myWizardState.getString(ATTR_PROJECT_LOCATION));
// Do the project creation
myWizard.createProject();
// Make sure we created the project-level files
assertFilesExist(baseDir,
"build.gradle",
".gitignore",
"settings.gradle",
"gradle.properties",
"local.properties");
// Make sure we created the module files
File moduleBase = new File(baseDir, myWizardState.getString(FormFactorUtils.ATTR_MODULE_NAME));
assertFilesExist(moduleBase,
".gitignore",
"build.gradle",
"proguard-rules.pro",
"src/main/res/values/strings.xml",
"src/main/AndroidManifest.xml");
return moduleBase;
}
public void testCreateProjectNoActivityNoIconsLibrary() throws Exception {
myWizardState.put(ATTR_CREATE_ACTIVITY, false);
myWizardState.put(ATTR_CREATE_ICONS, false);
myWizardState.put(ATTR_IS_LIBRARY_MODULE, true);
setUpStandardProjectCreation();
File moduleDir = runCommonCreateProjectTest();
File gradleFile = new File(moduleDir, SdkConstants.FN_BUILD_GRADLE);
String gradleContents = TemplateUtils.readTextFile(gradleFile);
assertNotNull(gradleContents);
assertTrue(gradleContents.contains("apply plugin: 'com.android.library'"));
File manifestFile = new File(moduleDir, FileUtil.join("src", "main", SdkConstants.ANDROID_MANIFEST_XML));
String manifestContents = TemplateUtils.readTextFile(manifestFile);
assertNotNull(manifestContents);
assertFalse(manifestContents.contains("android:theme"));
assertFilesExist(moduleDir,
"src/main/java/com/test/package",
"src/main/res/drawable-hdpi/ic_launcher.png",
"src/main/res/drawable-mdpi/ic_launcher.png",
"src/main/res/drawable-xhdpi/ic_launcher.png",
"src/main/res/drawable-xxhdpi/ic_launcher.png");
}
public void testCreateProjectNoActivityNoIconsApplication() throws Exception {
myWizardState.put(ATTR_CREATE_ACTIVITY, false);
myWizardState.put(ATTR_CREATE_ICONS, false);
myWizardState.put(ATTR_IS_LIBRARY_MODULE, false);
setUpStandardProjectCreation();
File moduleDir = runCommonCreateProjectTest();
File gradleFile = new File(moduleDir, "build.gradle");
String gradleContents = TemplateUtils.readTextFile(gradleFile);
assertNotNull(gradleContents);
assertTrue(gradleContents.contains("apply plugin: 'com.android.application'"));
File manifestFile = new File(moduleDir, FileUtil.join("src", "main", SdkConstants.ANDROID_MANIFEST_XML));
String manifestContents = TemplateUtils.readTextFile(manifestFile);
assertNotNull(manifestContents);
assertTrue(manifestContents.contains("android:theme"));
assertFilesExist(moduleDir,
"src/main/res/values/styles.xml",
"src/main/java/com/test/package",
"src/main/res/drawable-hdpi/ic_launcher.png",
"src/main/res/drawable-mdpi/ic_launcher.png",
"src/main/res/drawable-xhdpi/ic_launcher.png",
"src/main/res/drawable-xxhdpi/ic_launcher.png");
}
@SuppressWarnings("unchecked")
public void testCreateProjectWithActivityWithIcons() throws Exception {
myWizardState.put(ATTR_CREATE_ACTIVITY, true);
myWizardState.put(ATTR_CREATE_ICONS, true);
myWizardState.put(ATTR_IS_LIBRARY_MODULE, false);
AssetStudioAssetGenerator launcherIconStateMock = mock(AssetStudioAssetGenerator.class);
NewProjectWizardState spyState = spy(myWizardState);
myWizard.myWizardState = spyState;
myWizard.myAssetGenerator = launcherIconStateMock;
TemplateWizardState activityStateMock = spy(myWizardState.getActivityTemplateState());
Template activityTemplateMock = mock(Template.class);
when(activityStateMock.getTemplate()).thenReturn(activityTemplateMock);
when(spyState.getActivityTemplateState()).thenReturn(activityStateMock);
setUpStandardProjectCreation();
File moduleRoot = runCommonCreateProjectTest();
verify(launcherIconStateMock).outputImagesIntoDefaultVariant(eq(moduleRoot));
verify(activityTemplateMock).render(eq(moduleRoot), eq(moduleRoot),
eq(myWizardState.myActivityTemplateState.myParameters));
}
@SuppressWarnings("unchecked")
public void testCreateProjectNoActivityNoIcons() throws Exception {
myWizardState.put(ATTR_CREATE_ACTIVITY, false);
myWizardState.put(ATTR_CREATE_ICONS, false);
myWizardState.put(ATTR_IS_LIBRARY_MODULE, false);
AssetStudioAssetGenerator launcherIconStateMock = mock(AssetStudioAssetGenerator.class);
NewProjectWizardState spyState = spy(myWizardState);
myWizard.myWizardState = spyState;
myWizard.myAssetGenerator = launcherIconStateMock;
TemplateWizardState activityStateMock = spy(myWizardState.getActivityTemplateState());
Template activityTemplateMock = mock(Template.class);
when(activityStateMock.getTemplate()).thenReturn(activityTemplateMock);
when(spyState.getActivityTemplateState()).thenReturn(activityStateMock);
setUpStandardProjectCreation();
runCommonCreateProjectTest();
verifyZeroInteractions(activityStateMock, activityTemplateMock, launcherIconStateMock);
}
@SuppressWarnings("unchecked")
public void testCreateProjectWithWeirdFileNames() throws Exception {
myWizardState.put(ATTR_CREATE_ACTIVITY, false);
myWizardState.put(ATTR_CREATE_ICONS, false);
myWizardState.put(ATTR_IS_LIBRARY_MODULE, false);
String projectName = "ThisIsAProjectName";
myWizardState.put(ATTR_APP_TITLE, projectName);
myWizardState.put(ATTR_PACKAGE_NAME, "com.test.package");
myWizardState.put(FormFactorUtils.ATTR_MODULE_NAME, MODULE_NAME);
File baseDir;
// Check apostrophe in file path
baseDir = new File(getProject().getBasePath(), "test'orama");
myWizardState.put(ATTR_PROJECT_LOCATION, baseDir.getPath());
runCommonCreateProjectTest();
resetDirectoryParams();
// The following characters are reserved on a Windows system
if (!System.getProperty("os.name").startsWith("Windows")) {
// Check quote in file path
baseDir = new File(getProject().getBasePath(), "test\"orama");
myWizardState.put(ATTR_PROJECT_LOCATION, baseDir.getPath());
runCommonCreateProjectTest();
resetDirectoryParams();
// Check unicode characters
baseDir = new File(getProject().getBasePath(), "test\uD83D\uDCA9orama");
myWizardState.put(ATTR_PROJECT_LOCATION, baseDir.getPath());
runCommonCreateProjectTest();
resetDirectoryParams();
// Check < and > characters
baseDir = new File(getProject().getBasePath(), "test<orama");
myWizardState.put(ATTR_PROJECT_LOCATION, baseDir.getPath());
runCommonCreateProjectTest();
resetDirectoryParams();
baseDir = new File(getProject().getBasePath(), "test>orama");
myWizardState.put(ATTR_PROJECT_LOCATION, baseDir.getPath());
runCommonCreateProjectTest();
resetDirectoryParams();
}
}
private void resetDirectoryParams() {
myWizardState.myParameters.remove(ATTR_RES_OUT);
myWizardState.myParameters.remove(ATTR_SRC_OUT);
myWizardState.myParameters.remove(ATTR_MANIFEST_OUT);
}
}