blob: 64c458474299df4230807c053fea2e6319c94389 [file] [log] [blame]
/*
* Copyright (C) 2014 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.tests.gui.layout;
import com.android.builder.model.AndroidProject;
import com.android.builder.model.ApiVersion;
import com.android.tools.idea.gradle.IdeaAndroidProject;
import com.android.tools.idea.tests.gui.framework.GuiTestCase;
import com.android.tools.idea.tests.gui.framework.IdeGuiTest;
import com.android.tools.idea.tests.gui.framework.fixture.EditorFixture;
import com.android.tools.idea.tests.gui.framework.fixture.FileFixture;
import com.android.tools.idea.tests.gui.framework.fixture.IdeFrameFixture;
import com.android.tools.idea.tests.gui.framework.fixture.InspectionsFixture;
import com.android.tools.idea.tests.gui.framework.fixture.layout.LayoutEditorFixture;
import com.android.tools.idea.tests.gui.framework.fixture.layout.RenderErrorPanelFixture;
import com.android.tools.idea.tests.gui.framework.fixture.newProjectWizard.ConfigureAndroidProjectStepFixture;
import com.android.tools.idea.tests.gui.framework.fixture.newProjectWizard.NewProjectWizardFixture;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.roots.LanguageLevelModuleExtension;
import com.intellij.openapi.roots.LanguageLevelModuleExtensionImpl;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import static com.android.tools.idea.npw.FormFactorUtils.FormFactor.MOBILE;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static org.fest.assertions.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class NewProjectTest extends GuiTestCase {
@Test @IdeGuiTest
public void testCreateNewMobileProject() {
IdeFrameFixture projectFrame = newProject("Test Application").create();
FileFixture layoutFile = projectFrame.findExistingFileByRelativePath("app/src/main/res/layout/activity_main.xml");
layoutFile.requireOpenAndSelected();
// Verify state of project
projectFrame.requireModuleCount(2);
IdeaAndroidProject appAndroidModel = projectFrame.getAndroidProjectForModule("app");
assertThat(appAndroidModel.getVariantNames()).as("variants").containsOnly("debug", "release");
assertThat(appAndroidModel.getSelectedVariant().getName()).as("selected variant").isEqualTo("debug");
AndroidProject model = appAndroidModel.getAndroidProject();
ApiVersion minSdkVersion = model.getDefaultConfig().getProductFlavor().getMinSdkVersion();
assertNotNull("minSdkVersion", minSdkVersion);
assertThat(minSdkVersion.getApiString()).as("minSdkVersion API").isEqualTo("19");
// Make sure that the activity registration uses the relative syntax
// (regression test for https://code.google.com/p/android/issues/detail?id=76716)
EditorFixture editor = projectFrame.getEditor();
editor.open("app/src/main/AndroidManifest.xml");
int offset = editor.findOffset("\".^MainActivity\"");
assertTrue(offset != -1);
// Creating a project with minSdkVersion 19 should leave the Java language level as Java 6
// For L and higher we use Java 7 language level; that is tested separately in testLanguageLevelForApi21
assertThat(appAndroidModel.getJavaLanguageLevel()).as("Gradle Java language level").isSameAs(LanguageLevel.JDK_1_6);
LanguageLevelProjectExtension projectExt = LanguageLevelProjectExtension.getInstance(projectFrame.getProject());
assertThat(projectExt.getLanguageLevel()).as("Project Java language level").isSameAs(LanguageLevel.JDK_1_6);
for (Module module : ModuleManager.getInstance(projectFrame.getProject()).getModules()) {
LanguageLevelModuleExtension moduleExt = LanguageLevelModuleExtensionImpl.getInstance(module);
assertThat(moduleExt.getLanguageLevel()).as("Gradle Java language level in module " + module.getName()).isNull();
}
}
@Test @IdeGuiTest
public void testNoWarningsInNewProjects() throws IOException {
// Creates a new default project, and checks that if we run Analyze > Inspect Code, there are no warnings.
// This checks that our (default) project templates are warnings-clean.
// The test then proceeds to make a couple of edits and checks that these do not generate additional
// warnings either.
IdeFrameFixture projectFrame = newProject("Test Application").create();
// Insert resValue statements which should not add warnings (since they are generated files; see
// https://code.google.com/p/android/issues/detail?id=76715
EditorFixture editor = projectFrame.getEditor();
String buildGradlePath = "app/build.gradle";
editor.open(buildGradlePath, EditorFixture.Tab.EDITOR);
editor.moveTo(editor.findOffset("defaultConfig {", null, true));
editor.enterText("\nresValue \"string\", \"foo\", \"Typpo Here\"");
projectFrame.requireEditorNotification("Gradle files have changed since last project sync").performAction("Sync Now");
projectFrame.waitForGradleProjectSyncToFinish();
InspectionsFixture inspections = projectFrame.inspectCode();
assertEquals("Test Application\n" +
// This warning is from the "foo" string we created in the Gradle resValue declaration above
" Android Lint\n" +
" Unused resources\n" +
" app\n" +
" The resource 'R.string.foo' appears to be unused\n" +
// This warning is wrong: https://code.google.com/p/android/issues/detail?id=76719
" Assignment issues\n" +
" Incompatible type assignments\n" +
" app\n" +
" 'dependencies' cannot be applied to '(groovy.lang.Closure)'\n" +
" build.gradle\n" +
" 'dependencies' cannot be applied to '(groovy.lang.Closure)'\n",
inspections.getResults());
}
@Test @IdeGuiTest
public void testRenderResourceInitialization() throws IOException {
// Regression test for https://code.google.com/p/android/issues/detail?id=76966
IdeFrameFixture projectFrame = newProject("Test Application").withBriefNames().withMinSdk("9").create();
EditorFixture editor = projectFrame.getEditor();
editor.requireName("activity_a.xml");
LayoutEditorFixture layoutEditor = editor.getLayoutEditor(false);
assertNotNull("Layout editor was not showing", layoutEditor);
layoutEditor.waitForNextRenderToFinish();
projectFrame.invokeProjectMake();
layoutEditor.waitForNextRenderToFinish();
layoutEditor.requireRenderSuccessful();
projectFrame.waitForBackgroundTasksToFinish();
}
@Test @IdeGuiTest
public void testLanguageLevelForApi21() {
// Verifies that creating a project with L will set the language level correctly
// both in the generated Gradle model as well as in the synced project and modules
// "20+" here should change to 21 as soon as L goes out of preview state
IdeFrameFixture projectFrame = newProject("Test Application").withBriefNames().withMinSdk("21").create();
IdeaAndroidProject appAndroidModel = projectFrame.getAndroidProjectForModule("app");
AndroidProject model = appAndroidModel.getAndroidProject();
ApiVersion minSdkVersion = model.getDefaultConfig().getProductFlavor().getMinSdkVersion();
assertNotNull("minSdkVersion", minSdkVersion);
// If this test fails, verify that
// (1) you have the L preview installed in the SDK on the test machine
// (2) the associated JDK is JDK 7 or higher
assertThat(minSdkVersion.getApiString()).as("minSdkVersion API").isEqualTo("L");
assertThat(appAndroidModel.getJavaLanguageLevel()).as("Gradle Java language level").isSameAs(LanguageLevel.JDK_1_7);
LanguageLevelProjectExtension projectExt = LanguageLevelProjectExtension.getInstance(projectFrame.getProject());
assertThat(projectExt.getLanguageLevel()).as("Project Java language level").isSameAs(LanguageLevel.JDK_1_7);
for (Module module : ModuleManager.getInstance(projectFrame.getProject()).getModules()) {
LanguageLevelModuleExtension moduleExt = LanguageLevelModuleExtensionImpl.getInstance(module);
assertThat(moduleExt.getLanguageLevel()).as("Gradle Java language level in module " + module.getName()).isNull();
}
}
@Test @IdeGuiTest
public void testStillBuildingMessage() throws Exception {
// Creates a new project with minSdk 15, which should use appcompat.
// Check that if there are render-error messages on first render,
// they don't include "Missing Styles" (should now talk about project building instead)
IdeFrameFixture projectFrame = newProject("Test Application").withBriefNames().withMinSdk("15").withoutSync().create();
EditorFixture editor = projectFrame.getEditor();
editor.open("app/src/main/res/layout/activity_a.xml", EditorFixture.Tab.DESIGN);
LayoutEditorFixture layoutEditor = editor.getLayoutEditor(true);
assertNotNull(layoutEditor);
layoutEditor.waitForNextRenderToFinish();
RenderErrorPanelFixture renderErrors = layoutEditor.getRenderErrors();
String html = renderErrors.getErrorHtml();
// We could be showing an error message, but if we do, it should *not* say missing styles
// (should only be showing project render errors)
assertFalse(html, html.contains("Missing styles"));
}
@NotNull
private NewProjectDescriptor newProject(@NotNull String name) {
return new NewProjectDescriptor(name);
}
/**
* Describes a new test project to be created.
*/
private class NewProjectDescriptor {
private String myActivity = "MainActivity";
private String myPkg = "com.android.test.app";
private String myMinSdk = "19";
private String myName = "TestProject";
private String myDomain = "com.android";
private boolean myWaitForSync = true;
private NewProjectDescriptor(@NotNull String name) {
withName(name);
}
/**
* Set a custom package to use in the new project
*/
NewProjectDescriptor withPackageName(@NotNull String pkg) {
myPkg = pkg;
return this;
}
/**
* Set a new project name to use for the new project
*/
NewProjectDescriptor withName(@NotNull String name) {
myName = name;
return this;
}
/**
* Set a custom activity name to use in the new project
*/
NewProjectDescriptor withActivity(@NotNull String activity) {
myActivity = activity;
return this;
}
/**
* Set a custom minimum SDK version to use in the new project
*/
NewProjectDescriptor withMinSdk(@NotNull String minSdk) {
myMinSdk = minSdk;
return this;
}
/**
* Set a custom company domain to enter in the new project wizard
*/
NewProjectDescriptor withCompanyDomain(@NotNull String domain) {
myDomain = domain;
return this;
}
/**
* Picks brief names in order to make the test execute faster (less slow typing in name text fields)
*/
NewProjectDescriptor withBriefNames() {
withActivity("A").withCompanyDomain("C").withName("P").withPackageName("a.b");
return this;
}
/** Turns off the automatic wait-for-sync that normally happens on {@link #create} */
NewProjectDescriptor withoutSync() {
myWaitForSync = false;
return this;
}
/**
* Creates a project fixture for this description
*/
@NotNull
IdeFrameFixture create() {
findWelcomeFrame().clickNewProjectButton();
NewProjectWizardFixture newProjectWizard = findNewProjectWizard();
ConfigureAndroidProjectStepFixture configureAndroidProjectStep = newProjectWizard.getConfigureAndroidProjectStep();
configureAndroidProjectStep.enterApplicationName(myName).enterCompanyDomain(myDomain).enterPackageName(myPkg);
File projectPath = configureAndroidProjectStep.getLocationInFileSystem();
newProjectWizard.clickNext();
newProjectWizard.getConfigureFormFactorStep().selectMinimumSdkApi(MOBILE, myMinSdk);
newProjectWizard.clickNext();
// Skip "Add Activity" step
newProjectWizard.clickNext();
newProjectWizard.getChooseOptionsForNewFileStep().enterActivityName(myActivity);
newProjectWizard.clickFinish();
IdeFrameFixture projectFrame = findIdeFrame(myName, projectPath);
if (myWaitForSync) {
projectFrame.waitForGradleProjectSyncToFinish();
}
return projectFrame;
}
}
}