/*
* Copyright 2010 the original author or authors.
*
* 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 org.gradle.api.internal.project;
import org.apache.commons.io.FileUtils;
import org.gradle.StartParameter;
import org.gradle.api.artifacts.dsl.RepositoryHandler;
import org.gradle.api.initialization.ProjectDescriptor;
import org.gradle.api.internal.ClassGenerator;
import org.gradle.api.internal.DomainObjectContext;
import org.gradle.api.internal.Factory;
import org.gradle.api.internal.GradleInternal;
import org.gradle.api.internal.artifacts.ConfigurationContainerFactory;
import org.gradle.api.internal.artifacts.configurations.DependencyMetaDataProvider;
import org.gradle.api.internal.artifacts.configurations.ResolverProvider;
import org.gradle.api.internal.artifacts.dsl.DefaultRepositoryHandler;
import org.gradle.groovy.scripts.ScriptSource;
import org.gradle.groovy.scripts.StringScriptSource;
import org.gradle.groovy.scripts.UriScriptSource;
import org.gradle.util.MultiParentClassLoader;
import org.gradle.util.TemporaryFolder;
import org.jmock.Expectations;
import org.jmock.integration.junit4.JMock;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.jmock.lib.legacy.ClassImposteriser;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.File;
import java.io.IOException;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
/**
* @author Hans Dockter
*/
@RunWith(JMock.class)
public class ProjectFactoryTest {
private final JUnit4Mockery context = new JUnit4Mockery() {{
setImposteriser(ClassImposteriser.INSTANCE);
}};
private final MultiParentClassLoader buildScriptClassLoader = new MultiParentClassLoader(getClass().getClassLoader());
@Rule
public TemporaryFolder testDir = new TemporaryFolder();
private final File rootDir = testDir.getDir();
private final File projectDir = new File(rootDir, "project");
private ConfigurationContainerFactory configurationContainerFactory = context.mock(
ConfigurationContainerFactory.class);
private Factory<RepositoryHandler> repositoryHandlerFactory = context.mock(Factory.class);
private DefaultRepositoryHandler repositoryHandler = context.mock(DefaultRepositoryHandler.class);
private StartParameter startParameterStub = new StartParameter();
private ServiceRegistryFactory serviceRegistryFactory = new TopLevelBuildServiceRegistry(new GlobalServicesRegistry(), startParameterStub);
private ClassGenerator classGeneratorMock = serviceRegistryFactory.get(ClassGenerator.class);
private GradleInternal gradle = context.mock(GradleInternal.class);
private ProjectFactory projectFactory;
@Before
public void setUp() throws Exception {
startParameterStub.setGradleUserHomeDir(testDir.createDir("home"));
context.checking(new Expectations() {{
allowing(repositoryHandlerFactory).create();
will(returnValue(repositoryHandler));
}});
final ServiceRegistryFactory gradleServices = serviceRegistryFactory.createFor(gradle);
context.checking(new Expectations() {{
allowing(gradle).getServices();
will(returnValue(gradleServices));
allowing(gradle).getStartParameter();
will(returnValue(startParameterStub));
allowing(configurationContainerFactory).createConfigurationContainer(with(any(ResolverProvider.class)),
with(any(DependencyMetaDataProvider.class)), with(any(DomainObjectContext.class)));
allowing(gradle).getProjectRegistry();
will(returnValue(gradleServices.get(IProjectRegistry.class)));
allowing(gradle).getScriptClassLoader();
will(returnValue(buildScriptClassLoader));
allowing(gradle).getGradleUserHomeDir();
will(returnValue(new File("gradleUserHomeDir")));
ignoring(gradle).getProjectEvaluationBroadcaster();
}});
projectFactory = new ProjectFactory(null, classGeneratorMock);
}
@Test
public void testConstructsRootProjectWithBuildFile() throws IOException {
File buildFile = new File(rootDir, "build.gradle");
FileUtils.writeStringToFile(buildFile, "build");
ProjectDescriptor descriptor = descriptor("somename", rootDir, buildFile, "build.gradle");
DefaultProject project = projectFactory.createProject(descriptor, null, gradle);
assertEquals("somename", project.getName());
assertEquals(buildFile, project.getBuildFile());
assertNull(project.getParent());
assertSame(rootDir, project.getRootDir());
assertSame(rootDir, project.getProjectDir());
assertSame(project, project.getRootProject());
checkProjectResources(project);
assertThat(project.getBuildScriptSource(), instanceOf(UriScriptSource.class));
assertThat(project.getBuildScriptSource().getDisplayName(), startsWith("build file "));
assertThat(project.getBuildScriptSource().getResource().getFile(), equalTo(buildFile));
}
@Test
public void testConstructsChildProjectWithBuildFile() throws IOException {
File buildFile = new File(projectDir, "build.gradle");
FileUtils.writeStringToFile(buildFile, "build");
ProjectDescriptor rootDescriptor = descriptor("root");
ProjectDescriptor parentDescriptor = descriptor("parent");
ProjectDescriptor projectDescriptor = descriptor("somename", projectDir, buildFile, "build.gradle");
DefaultProject rootProject = projectFactory.createProject(rootDescriptor, null, gradle);
DefaultProject parentProject = projectFactory.createProject(parentDescriptor, rootProject, gradle);
DefaultProject project = projectFactory.createProject(projectDescriptor, parentProject, gradle);
assertEquals("somename", project.getName());
assertEquals(buildFile, project.getBuildFile());
assertSame(parentProject, project.getParent());
assertSame(rootDir, project.getRootDir());
assertSame(projectDir, project.getProjectDir());
assertSame(rootProject, project.getRootProject());
assertSame(project, parentProject.getChildProjects().get("somename"));
checkProjectResources(project);
assertThat(project.getBuildScriptSource(), instanceOf(UriScriptSource.class));
assertThat(project.getBuildScriptSource().getDisplayName(), startsWith("build file "));
assertThat(project.getBuildScriptSource().getResource().getFile(), equalTo(buildFile));
}
@Test
public void testAddsProjectToProjectRegistry() throws IOException {
ProjectDescriptor rootDescriptor = descriptor("root");
ProjectDescriptor parentDescriptor = descriptor("somename");
DefaultProject rootProject = projectFactory.createProject(rootDescriptor, null, gradle);
DefaultProject project = projectFactory.createProject(parentDescriptor, rootProject, gradle);
assertThat(gradle.getProjectRegistry().getProject(":somename"), sameInstance((ProjectIdentifier) project));
}
@Test
public void testUsesEmptyBuildFileWhenBuildFileIsMissing() {
DefaultProject rootProject = projectFactory.createProject(descriptor("root"), null, gradle);
DefaultProject project = projectFactory.createProject(descriptor("somename", projectDir), rootProject, gradle);
assertThat(project.getBuildScriptSource(), instanceOf(StringScriptSource.class));
assertThat(project.getBuildScriptSource().getDisplayName(), equalTo("empty build file"));
assertThat(project.getBuildScriptSource().getResource().getText(), equalTo(""));
}
@Test
public void testConstructsRootProjectWithEmbeddedBuildScript() {
ScriptSource expectedScriptSource = new StringScriptSource("script", "content");
ProjectFactory projectFactory = new ProjectFactory(expectedScriptSource, classGeneratorMock);
DefaultProject project = projectFactory.createProject(descriptor("somename"), null, gradle);
assertEquals("somename", project.getName());
assertSame(rootDir, project.getRootDir());
assertSame(rootDir, project.getProjectDir());
assertNull(project.getParent());
assertSame(project, project.getRootProject());
assertNotNull(project.getConvention());
checkProjectResources(project);
assertSame(project.getBuildScriptSource(), expectedScriptSource);
}
private ProjectDescriptor descriptor(String name) {
return descriptor(name, rootDir);
}
private ProjectDescriptor descriptor(String name, File projectDir) {
return descriptor(name, projectDir, new File(projectDir, "build.gradle"), "build.gradle");
}
private ProjectDescriptor descriptor(final String name, final File projectDir, final File buildFile,
final String buildFileName) {
final ProjectDescriptor descriptor = context.mock(ProjectDescriptor.class, name);
context.checking(new Expectations() {{
allowing(descriptor).getName();
will(returnValue(name));
allowing(descriptor).getProjectDir();
will(returnValue(projectDir));
allowing(descriptor).getBuildFile();
will(returnValue(buildFile));
allowing(descriptor).getBuildFileName();
will(returnValue(buildFileName));
}});
return descriptor;
}
private void checkProjectResources(DefaultProject project) {
assertSame(gradle, project.getGradle());
}
}