Package org.netbeans.gradle.model.java

Source Code of org.netbeans.gradle.model.java.MultiLevelJavaProjectTest

package org.netbeans.gradle.model.java;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.gradle.tooling.ProjectConnection;
import org.gradle.tooling.model.GradleProject;
import org.gradle.tooling.model.eclipse.EclipseProject;
import org.gradle.tooling.model.idea.IdeaModule;
import org.gradle.tooling.model.idea.IdeaProject;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.netbeans.gradle.model.BuildInfoBuilder;
import org.netbeans.gradle.model.BuilderIssue;
import org.netbeans.gradle.model.BuilderResult;
import org.netbeans.gradle.model.FetchedModels;
import org.netbeans.gradle.model.FetchedModelsOrError;
import org.netbeans.gradle.model.GenericModelFetcher;
import org.netbeans.gradle.model.GenericProjectProperties;
import org.netbeans.gradle.model.GradleBuildInfoQuery;
import org.netbeans.gradle.model.GradleMultiProjectDef;
import org.netbeans.gradle.model.GradleProjectTree;
import org.netbeans.gradle.model.GradleTaskID;
import org.netbeans.gradle.model.api.GradleProjectInfoQuery;
import org.netbeans.gradle.model.api.ProjectInfoBuilder;
import org.netbeans.gradle.model.internal.ConstBuilders;
import org.netbeans.gradle.model.util.CollectionUtils;
import org.netbeans.gradle.model.util.Exceptions;
import org.netbeans.gradle.model.util.ProjectConnectionTask;
import org.netbeans.gradle.model.util.SourceSetVerification;
import org.netbeans.gradle.model.util.TestUtils;
import org.netbeans.gradle.model.util.ZipUtils;

import static org.junit.Assert.*;
import static org.netbeans.gradle.model.java.InfoQueries.*;
import static org.netbeans.gradle.model.util.TestUtils.*;

public class MultiLevelJavaProjectTest {
    private static final String ROOT_NAME = "gradle-multi-level";

    private static File tempFolder = null;
    private static File testedProjectDir = null;

    @BeforeClass
    public static void setUpClass() throws IOException {
        tempFolder = ZipUtils.unzipResourceToTemp(MultiLevelJavaProjectTest.class, "gradle-multi-level.zip");
        testedProjectDir = new File(tempFolder, ROOT_NAME);
    }

    @AfterClass
    public static void tearDownClass() throws IOException {
        if (tempFolder != null) {
            ZipUtils.recursiveDelete(tempFolder);
        }
    }

    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }

    private static File getProjectDir(String... subprojectNames) throws IOException {
        return getSubPath(testedProjectDir, subprojectNames);
    }

    private void runTestForSubProject(String projectName, ProjectConnectionTask task) {
        TestUtils.runTestForSubProject(testedProjectDir, projectName, task);
    }

    private static Set<String> toTaskNames(Collection<GradleTaskID> tasks) {
        Set<String> result = new LinkedHashSet<String>(2 * tasks.size());
        for (GradleTaskID task: tasks) {
            result.add(task.getName());
        }
        return result;
    }

    private static Set<String> mustHaveTasks(
            String relativeProjectPath,
            Collection<GradleTaskID> tasks,
            String... expectedNames) {
        String taskPrefix = ":" + relativeProjectPath + ":";

        Set<String> otherTasks = new LinkedHashSet<String>();

        Set<String> expectedSet = new LinkedHashSet<String>(Arrays.asList(expectedNames));
        for (GradleTaskID task: tasks) {
            String name = task.getName();
            assertEquals(taskPrefix + name, task.getFullName());

            if (!expectedSet.remove(name)) {
                otherTasks.add(name);
            }
        }

        if (!expectedSet.isEmpty()) {
            fail("The following tasks were not found but were expected: " + expectedSet
                    + ". The project has the following tasks: " + toTaskNames(tasks));
        }

        return otherTasks;
    }

    private static void testBasicInfoForProject(
            String relativeProjectName,
            GradleMultiProjectDef projectDef) throws IOException {
        assertNotNull("Must have a GradleMultiProjectDef.", projectDef);

        String[] projectPathParts = relativeProjectName.length() > 0
                ? relativeProjectName.split(Pattern.quote(":"))
                : new String[0];

        String projectPath = ":" + relativeProjectName;
        String projectName = projectPathParts.length > 0
                ? projectPathParts[projectPathParts.length - 1]
                : ROOT_NAME;

        GradleProjectTree projectTree = projectDef.getMainProject();
        GenericProjectProperties genericProperties = projectTree.getGenericProperties();

        String fullName = genericProperties.getProjectFullName();
        assertEquals(projectPath, fullName);

        String simpleName = genericProperties.getProjectName();
        assertEquals(projectName, simpleName);

        File projectDir = genericProperties.getProjectDir();
        assertEquals(getProjectDir(projectPathParts), projectDir.getCanonicalFile());
    }

    private void testBasicInfoForProjectWithTasks(
            final String relativeProjectName,
            final String[] expectedTasks,
            final String[] unexpectedTasks) {

        runTestForSubProject(relativeProjectName, new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                GradleMultiProjectDef projectDef = fetchProjectDef(connection);
                testBasicInfoForProject(relativeProjectName, projectDef);

                GradleProjectTree mainProject = projectDef.getMainProject();
                GenericProjectProperties genericProperties = mainProject.getGenericProperties();

                assertEquals("Build script for the project must be build.gradle.",
                        new File(genericProperties.getProjectDir(), "build.gradle"),
                        genericProperties.getBuildScript());

                Collection<GradleTaskID> tasks = mainProject.getTasks();
                Set<String> remainingTasks = mustHaveTasks(relativeProjectName, tasks, expectedTasks);

                for (String task: unexpectedTasks) {
                    if (remainingTasks.contains(task)) {
                        fail("The project must not have the following task: " + task);
                    }
                }
            }
        });
    }

    private static String[] groovyProjects() {
        return new String[] {
            "apps:app1",
        };
    }

    private static String[] javaProjects() {
        return new String[] {
            "libs:lib3:lib1",
            "apps:app2",
            "libs:lib1",
            "libs:lib2",
            "libs:lib3",
            "libs:lib3:lib2",
        };
    }

    private static String[] concatArrays(String[]... arrays) {
        int length = 0;
        for (String[] array: arrays) {
            length += array.length;
        }

        String[] result = new String[length];
        int offset = 0;
        for (String[] array: arrays) {
            System.arraycopy(array, 0, result, offset, array.length);
            offset += array.length;
        }
        return result;
    }

    private static String[] subprojects() {
        return concatArrays(groovyProjects(), javaProjects());
    }

    private static String[] allProjects() {
        return concatArrays(new String[]{""}, subprojects());
    }

    @Test
    public void testBasicInfoForJavaProjects() {
        String[] expectedTasks = {"clean", "build", "compileJava"};
        String[] unexpectedTasks = {"wrapper"};

        for (String relativeProjectName: javaProjects()) {
            testBasicInfoForProjectWithTasks(relativeProjectName, expectedTasks, unexpectedTasks);
        }
    }

    @Test
    public void testBasicInfoForGroovyProjects() {
        String[] expectedTasks = {"clean", "build", "compileJava", "compileGroovy"};
        String[] unexpectedTasks = {"wrapper"};

        for (String relativeProjectName: groovyProjects()) {
            testBasicInfoForProjectWithTasks(relativeProjectName, expectedTasks, unexpectedTasks);
        }
    }

    @Test
    public void testBasicInfoForRootProject() {
        String[] expectedTasks = {};
        String[] unexpectedTasks = {"compileJava"};

        testBasicInfoForProjectWithTasks("", expectedTasks, unexpectedTasks);
    }

    private static void assertNoProblem(Throwable issue) {
        if (issue != null) {
            Exceptions.throwUnchecked(issue);
        }
    }

    private static JavaClassPaths classPathsOfSourceSet(JavaSourcesModel model, String sourceSetName) {
        for (JavaSourceSet sourceSet: model.getSourceSets()) {
            if (sourceSetName.equals(sourceSet.getName())) {
                assertNoProblem(sourceSet.getCompileClassPathProblem());
                assertNoProblem(sourceSet.getRuntimeClassPathProblem());
                return sourceSet.getClasspaths();
            }
        }

        throw new AssertionError("Missing source set: " + sourceSetName);
    }

    private Map<File, String> parseProjectDependencies(String... projectDependencies) throws IOException {
        Map<File, String> result = CollectionUtils.newHashMap(projectDependencies.length);
        for (String dep: projectDependencies) {
            String[] nameParts = dep.split(Pattern.quote(":"));
            String name = nameParts[nameParts.length - 1];
            File projectDir = getProjectDir(nameParts);
            result.put(getSubPath(projectDir, "build", "libs", name + ".jar"), dep);
        }
        return result;
    }

    private void verifyProjectDependencies(Set<File> files, String... projectDependencies) throws IOException {
        Map<File, String> expected = parseProjectDependencies(projectDependencies);
        for (Map.Entry<File, String> entry: expected.entrySet()) {
            if (!files.contains(entry.getKey())) {
                fail("Expected project dependency " + entry.getValue());
            }
        }
    }

    private void verifyArtifact(Set<File> files, String artifactName, String version) {
        for (File file: files) {
            String name = file.getName();
            if (name.contains(artifactName) && name.contains(version)) {
                return;
            }
        }

        fail("Missing required artifact: " + artifactName + ":" + version);
    }

    private void verifyTestClassPath(Set<File> files) {
        verifyArtifact(files, "junit", "4.11");
        verifyArtifact(files, "mockito-core", "1.9.5");
    }

    private void testJavaSourcesModelForJavaProject(
            String relativeProjectName,
            final JavaSourcesModel expected,
            final String... projectDependencies) {

        runTestForSubProject(relativeProjectName, new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                JavaSourcesModel sourcesModel
                        = fetchSingleProjectInfo(connection, JavaSourcesModelBuilder.COMPLETE);
                assertNotNull("Must have a JavaSourcesModel.", sourcesModel);
                SourceSetVerification.verifySourcesModelWithoutDependencies(expected, sourcesModel);

                JavaClassPaths mainClassPaths = classPathsOfSourceSet(sourcesModel, "main");
                verifyProjectDependencies(mainClassPaths.getCompileClasspaths(), projectDependencies);
                verifyProjectDependencies(mainClassPaths.getRuntimeClasspaths(), projectDependencies);

                JavaClassPaths testClassPaths = classPathsOfSourceSet(sourcesModel, "test");
                verifyTestClassPath(testClassPaths.getCompileClasspaths());
                verifyTestClassPath(testClassPaths.getRuntimeClasspaths());

                JavaModelTests.checkNoDependencyResolultionError(sourcesModel);
            }
        });
    }

    @Test
    public void testJavaSourcesModel() throws IOException {
        testJavaSourcesModelForJavaProject("apps:app1", sourcesOfApp1(), "libs:lib1", "libs:lib2");
        testJavaSourcesModelForJavaProject("apps:app2", sourcesOfApp2(), "libs:lib1", "libs:lib2");
        testJavaSourcesModelForJavaProject("libs:lib1", sourcesOfLib1(), "libs:lib2");
        testJavaSourcesModelForJavaProject("libs:lib2", sourcesOfLib2());
        testJavaSourcesModelForJavaProject("libs:lib3", sourcesOfLib3());
        testJavaSourcesModelForJavaProject("libs:lib3:lib1", sourcesOfLib3Lib1());
        testJavaSourcesModelForJavaProject("libs:lib3:lib2", sourcesOfLib3Lib2());
    }

    @Test
    public void testJavaSourcesModelForRoot() throws IOException {
        runTestForSubProject("", new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                JavaSourcesModel sourcesModel
                        = fetchSingleProjectInfo(connection, JavaSourcesModelBuilder.ONLY_COMPILE);
                assertNull("Root must not have a JavaSourcesModel.", sourcesModel);
            }
        });
    }

    private void testJavaCompatibilityModel(String relativeProjectName) throws IOException {
        runTestForSubProject(relativeProjectName, new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                JavaCompatibilityModel compatibilityModel
                        = fetchSingleProjectInfo(connection, JavaCompatibilityModelBuilder.INSTANCE);
                assertNotNull("Must have a JavaCompatibilityModel.", compatibilityModel);

                assertEquals("1.5", compatibilityModel.getSourceCompatibility());
                assertEquals("1.7", compatibilityModel.getTargetCompatibility());
            }
        });
    }

    @Test
    public void testJavaCompatibilityModel() throws IOException {
        for (String project: subprojects()) {
            testJavaCompatibilityModel(project);
        }
    }

    @Test
    public void testJavaCompatibilityModelForRoot() throws IOException {
        runTestForSubProject("", new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                JavaCompatibilityModel compatibilityModel
                        = fetchSingleProjectInfo(connection, JavaCompatibilityModelBuilder.INSTANCE);
                assertNull("Root must not have a JavaCompatibilityModel.", compatibilityModel);
            }
        });
    }

    private void testJarOutputsModel(String relativeProjectPath) throws IOException {
        String[] projectPathParts = relativeProjectPath.split(Pattern.quote(":"));
        String name = projectPathParts[projectPathParts.length - 1];
        File projectDir = getProjectDir(projectPathParts);
        final File expectedJarPath = getSubPath(projectDir, "build", "libs", name + ".jar");

        runTestForSubProject(relativeProjectPath, new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                JarOutputsModel jarOutputs
                        = fetchSingleProjectInfo(connection, JarOutputsModelBuilder.INSTANCE);
                assertNotNull("Must have a JarOutputsModel.", jarOutputs);

                JarOutput mainJar = null;
                for (JarOutput jar: jarOutputs.getJars()) {
                    if (jar.getTaskName().equals("jar")) {
                        mainJar = jar;
                        break;
                    }
                }

                assertNotNull("Project must contain a main jar.", mainJar);
                assertEquals("Output jar must be at the expected location",
                        expectedJarPath, mainJar.getJar().getCanonicalFile());
            }
        });
    }

    @Test
    public void testJarOutputsModel() throws IOException {
        for (String project: subprojects()) {
            testJarOutputsModel(project);
        }
    }

    private Map<String, JavaTestTask> nameToTestTask(JavaTestModel testModel) {
        Collection<JavaTestTask> testTasks = testModel.getTestTasks();
        Map<String, JavaTestTask> result = CollectionUtils.newHashMap(testTasks.size());
        for (JavaTestTask testTask: testTasks) {
            if (result.put(testTask.getName(), testTask) != null) {
                fail("Test task has been retrieved multiple times: " + testTask.getName());
            }
        }
        return result;
    }

    private void verifyTestTask(Map<String, JavaTestTask> testTasks, String name, File expectedOutputDir) {
        JavaTestTask testTask = testTasks.get(name);
        assertNotNull("Expected test task with name " + name, testTask);
        assertEquals(name, testTask.getName());
        assertEquals(expectedOutputDir, testTask.getXmlOutputDir());
    }

    private void testJavaTestModel(String relativeProjectPath) throws IOException {
        String[] projectPathParts = relativeProjectPath.split(Pattern.quote(":"));
        File projectDir = getProjectDir(projectPathParts);
        final File expectedXmlPathTest = getSubPath(projectDir, "build", "test-results");
        final File expectedXmlPathMyTest = getSubPath(projectDir, "build", "my-test-custom-results");

        runTestForSubProject(relativeProjectPath, new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                JavaTestModel testModel
                        = fetchSingleProjectInfo(connection, JavaTestModelBuilder.INSTANCE);
                assertNotNull("Must have a JavaTestModel.", testModel);

                Map<String, JavaTestTask> testTasks = nameToTestTask(testModel);
                assertEquals("Must have a 2 test tasks.", 2, testTasks.size());

                verifyTestTask(testTasks, "test", expectedXmlPathTest);
                verifyTestTask(testTasks, "myTest", expectedXmlPathMyTest);
            }
        });
    }

    @Test
    public void testJavaTestModel() throws IOException {
        for (String project: subprojects()) {
            testJavaTestModel(project);
        }
    }

    @Test
    public void testJavaTestModelForRoot() throws IOException {
         runTestForSubProject("", new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                JavaTestModel testModel
                        = fetchSingleProjectInfo(connection, JavaTestModelBuilder.INSTANCE);
                assertNull("Root project must not have a JavaTestModel.", testModel);
            }
        });
    }

    @Test
    public void testJarOutputsModelForRoot() throws IOException {
        runTestForSubProject("", new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                JarOutputsModel jarOutputs
                        = fetchSingleProjectInfo(connection, JarOutputsModelBuilder.INSTANCE);
                assertNull("Root project must not have a JarOutputsModel.", jarOutputs);
            }
        });
    }

    @Test
    public void testWarFoldersModel() throws IOException {
        for (String project: allProjects()) {
            runTestForSubProject(project, new ProjectConnectionTask() {
                public void doTask(ProjectConnection connection) throws Exception {
                    WarFoldersModel warFolders
                            = fetchSingleProjectInfo(connection, WarFoldersModelBuilder.INSTANCE);
                    assertNull("Must not have a WarFoldersModel.", warFolders);
                }
            });
        }
    }

    @Test
    public void testCustomQuery() throws IOException {
        runTestForSubProject("", new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                String prefix = "testCustomQuery-";
                String result = fetchSingleBuildInfo(connection, TestBuilders.testBuildInfoBuilder(prefix));

                assertEquals(prefix + ROOT_NAME, result);
            }
        });
    }

    @Test
    public void testFailingProjectQuery() throws IOException {
        runTestForSubProject("", new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                String message = "testFailingProjectQuery-message";
                ProjectInfoBuilder<?> builder = TestBuilders.failingProjectInfoBuilder(message);
                BuilderResult result = fetchSingleProjectInfoWithError(connection, builder);
                assertNotNull("Required result for FailingProjectInfoBuilder.", result);

                BuilderIssue issue = result.getIssue();
                assertNotNull("Required issue for FailingProjectInfoBuilder", issue);

                assertEquals("Expected approriate builder name.", builder.getName(), issue.getName());
                String issueMessage = issue.getException().getMessage();
                if (!issueMessage.contains(message)) {
                    fail("Issue message is invalid: " + issueMessage);
                }
            }
        });
    }

    @Test
    public void testFailingBuildQuery() throws IOException {
        runTestForSubProject("", new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                String message = "testFailingBuildQuery-message";
                BuildInfoBuilder<?> builder = TestBuilders.failingBuildInfoBuilder(message);

                BuilderResult result = fetchSingleBuildInfoWithError(connection, builder);
                assertNotNull("Required result for FailingBuildInfoBuilder.", result);

                BuilderIssue issue = result.getIssue();
                assertNotNull("Required issue for FailingBuildInfoBuilder", issue);

                assertEquals("Expected approriate builder name.", builder.getName(), issue.getName());
                String issueMessage = issue.getException().getMessage();
                if (!issueMessage.contains(message)) {
                    fail("Issue message is invalid: " + issueMessage);
                }
            }
        });
    }

    private static Object getSingleBuildResult(List<BuilderResult> list) {
        BuilderResult result = CollectionUtils.getSingleElement(list);
        return result != null ? result.getResultIfNoIssue() : null;
    }

    private static FetchedModels verifyNoError(FetchedModelsOrError modelsOrError) {
        return InfoQueries.verifyNoError(modelsOrError);
    }

    @Test
    public void testManyQueries() throws IOException {
        Map<Object, List<GradleBuildInfoQuery<?>>> buildInfos
                = new HashMap<Object, List<GradleBuildInfoQuery<?>>>();

        Map<Object, List<GradleProjectInfoQuery<?>>> projectInfos
                = new HashMap<Object, List<GradleProjectInfoQuery<?>>>();

        Set<Class<?>> toolingModels = new HashSet<Class<?>>();

        projectInfos.put(0, Collections.<GradleProjectInfoQuery<?>>singletonList(
                InfoQueries.toCustomQuery(JarOutputsModelBuilder.INSTANCE)));
        projectInfos.put(1, Collections.<GradleProjectInfoQuery<?>>singletonList(
                InfoQueries.toCustomQuery(JavaCompatibilityModelBuilder.INSTANCE)));
        projectInfos.put(2, Collections.<GradleProjectInfoQuery<?>>singletonList(
                InfoQueries.toCustomQuery(JavaSourcesModelBuilder.COMPLETE)));
        projectInfos.put(3, Collections.<GradleProjectInfoQuery<?>>singletonList(
                InfoQueries.toCustomQuery(WarFoldersModelBuilder.INSTANCE)));

        final String prefix = "testCustomQuery-";
        buildInfos.put(0, Collections.<GradleBuildInfoQuery<?>>singletonList(
                InfoQueries.toCustomQuery(TestBuilders.testBuildInfoBuilder(prefix))));

        toolingModels.add(IdeaProject.class);

        final GenericModelFetcher fetcher = new GenericModelFetcher(buildInfos, projectInfos, toolingModels);
        runTestForSubProject("apps:app1", new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                FetchedModels models = verifyNoError(fetcher.getModels(connection, TestUtils.defaultInit()));

                String buildInfo = (String)getSingleBuildResult(
                        models.getBuildInfoResults().get(0));
                assertEquals(prefix + ROOT_NAME, buildInfo);

                Map<Object, List<BuilderResult>> projectInfos
                        = models.getDefaultProjectModels().getProjectInfoResults();

                JarOutputsModel model1 = (JarOutputsModel)getSingleBuildResult(projectInfos.get(0));
                JavaCompatibilityModel model2 = (JavaCompatibilityModel)getSingleBuildResult(projectInfos.get(1));
                JavaSourcesModel model3 = (JavaSourcesModel)getSingleBuildResult(projectInfos.get(2));
                WarFoldersModel model4 = (WarFoldersModel)getSingleBuildResult(projectInfos.get(3));

                assertNotNull(model1);
                assertNotNull(model2);
                assertNotNull(model3);
                assertNull(model4);
            }
        });
    }

    private static <T> T findResultOfType(Class<T> type, Collection<BuilderResult> builders) {
        for (BuilderResult builder: builders) {
            Object result = builder.getResultObject();
            if (type.isInstance(result)) {
                return type.cast(result);
            }
        }
        return null;
    }

    @Test
    public void testManyQueriesSingleKey() throws IOException {
        Map<Object, List<GradleBuildInfoQuery<?>>> buildInfos
                = new HashMap<Object, List<GradleBuildInfoQuery<?>>>();

        Map<Object, List<GradleProjectInfoQuery<?>>> projectInfos
                = new HashMap<Object, List<GradleProjectInfoQuery<?>>>();

        Set<Class<?>> toolingModels = new HashSet<Class<?>>();

        projectInfos.put(0, Arrays.<GradleProjectInfoQuery<?>>asList(
                InfoQueries.toCustomQuery(JarOutputsModelBuilder.INSTANCE),
                InfoQueries.toCustomQuery(JavaCompatibilityModelBuilder.INSTANCE),
                InfoQueries.toCustomQuery(JavaSourcesModelBuilder.COMPLETE),
                InfoQueries.toCustomQuery(WarFoldersModelBuilder.INSTANCE)));

        final String prefix = "testCustomQuery-";
        buildInfos.put(0, Collections.<GradleBuildInfoQuery<?>>singletonList(
                InfoQueries.toCustomQuery(TestBuilders.testBuildInfoBuilder(prefix))));

        toolingModels.add(IdeaProject.class);

        final GenericModelFetcher fetcher = new GenericModelFetcher(buildInfos, projectInfos, toolingModels);
        runTestForSubProject("apps:app1", new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                FetchedModels models = verifyNoError(fetcher.getModels(connection, TestUtils.defaultInit()));

                String buildInfo = (String)getSingleBuildResult(
                        models.getBuildInfoResults().get(0));
                assertEquals(prefix + ROOT_NAME, buildInfo);

                Map<Object, List<BuilderResult>> projectInfos
                        = models.getDefaultProjectModels().getProjectInfoResults();

                List<BuilderResult> results = projectInfos.get(0);
                assertNotNull("Must have results of query", results);

                assertEquals("Must have 3/4 queries.", 3, results.size());

                JarOutputsModel model1 = findResultOfType(JarOutputsModel.class, results);
                JavaCompatibilityModel model2 = findResultOfType(JavaCompatibilityModel.class, results);
                JavaSourcesModel model3 = findResultOfType(JavaSourcesModel.class, results);
                WarFoldersModel model4 = findResultOfType(WarFoldersModel.class, results);

                assertNotNull(model1);
                assertNotNull(model2);
                assertNotNull(model3);
                assertNull(model4);
            }
        });
    }

    private static void verifySerializationError(BuilderResult result) {
        assertNotNull("Must have a result with a serialization issue.", result);

        BuilderIssue issue = result.getIssue();
        assertNotNull("Must have a serialization issue.", issue);

        assertTrue("Cause must be a serialization error.",
                issue.getException().getMessage().contains("NotSerializableException"));
    }

    private static void verifyDeserializationError(BuilderResult result) {
        assertNotNull("Must have a result with a deserialization issue.", result);

        BuilderIssue issue = result.getIssue();
        assertNotNull("Must have a deserialization issue.", issue);

        assertTrue("Cause must be a ClassNotFoundException error.",
                issue.getException().getMessage().contains("ClassNotFoundException"));
    }

    @Test
    public void testSerializationFailures() throws IOException {
        Map<Object, List<GradleBuildInfoQuery<?>>> buildInfos
                = new HashMap<Object, List<GradleBuildInfoQuery<?>>>();

        Map<Object, List<GradleProjectInfoQuery<?>>> projectInfos
                = new HashMap<Object, List<GradleProjectInfoQuery<?>>>();

        Set<Class<?>> toolingModels = new HashSet<Class<?>>();

        final String projectInfoPrefix = "testSerializationFailures-project-";
        final String buildInfoPrefix = "testSerializationFailures-build-";

        projectInfos.put(0, Collections.<GradleProjectInfoQuery<?>>singletonList(
                InfoQueries.toCustomQuery(TestBuilders.testProjectInfoBuilder(projectInfoPrefix))));
        projectInfos.put(1, Collections.<GradleProjectInfoQuery<?>>singletonList(
                InfoQueries.toCustomQuery(TestBuilders.notSerializableProjectInfoBuilder())));
        projectInfos.put(2, Collections.<GradleProjectInfoQuery<?>>singletonList(
                InfoQueries.toCustomQuery(TestBuilders.notSerializableResultProjectInfoBuilder())));
        projectInfos.put(3, Collections.<GradleProjectInfoQuery<?>>singletonList(
                InfoQueries.toQueryWithKnownClassPath(TestBuilders.testProjectInfoBuilder(""))));
        projectInfos.put(4, Collections.<GradleProjectInfoQuery<?>>singletonList(
                InfoQueries.toQueryWithKnownClassPath(ConstBuilders.constProjectInfoBuilder(new SerializableObject()))));

        buildInfos.put(0, Collections.<GradleBuildInfoQuery<?>>singletonList(
                InfoQueries.toCustomQuery(TestBuilders.testBuildInfoBuilder(buildInfoPrefix))));
        buildInfos.put(1, Collections.<GradleBuildInfoQuery<?>>singletonList(
                InfoQueries.toCustomQuery(TestBuilders.notSerializableBuildInfoBuilder())));
        buildInfos.put(2, Collections.<GradleBuildInfoQuery<?>>singletonList(
                InfoQueries.toCustomQuery(TestBuilders.notSerializableResultBuildInfoBuilder())));
        buildInfos.put(3, Collections.<GradleBuildInfoQuery<?>>singletonList(
                InfoQueries.toQueryWithKnownClassPath(TestBuilders.testBuildInfoBuilder(""))));
        buildInfos.put(4, Collections.<GradleBuildInfoQuery<?>>singletonList(
                InfoQueries.toQueryWithKnownClassPath(ConstBuilders.constBuildInfoBuilder(new SerializableObject()))));

        toolingModels.add(IdeaProject.class);

        final GenericModelFetcher fetcher = new GenericModelFetcher(buildInfos, projectInfos, toolingModels);
        runTestForSubProject("apps:app1", new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                FetchedModels models = verifyNoError(fetcher.getModels(connection, TestUtils.defaultInit()));

                BuilderResult buildInfo1 = CollectionUtils
                        .getSingleElement(models.getBuildInfoResults().get(1));
                BuilderResult buildInfo2 = CollectionUtils
                        .getSingleElement(models.getBuildInfoResults().get(2));
                BuilderResult buildInfo3 = CollectionUtils
                        .getSingleElement(models.getBuildInfoResults().get(3));
                BuilderResult buildInfo4 = CollectionUtils
                        .getSingleElement(models.getBuildInfoResults().get(4));

                verifySerializationError(buildInfo1);
                verifySerializationError(buildInfo2);
                verifyDeserializationError(buildInfo3);
                verifyDeserializationError(buildInfo4);

                BuilderResult projectInfo1 = CollectionUtils.getSingleElement(
                        models.getDefaultProjectModels().getProjectInfoResults().get(1));
                BuilderResult projectInfo2 = CollectionUtils.getSingleElement(
                        models.getDefaultProjectModels().getProjectInfoResults().get(2));
                BuilderResult projectInfo3 = CollectionUtils.getSingleElement(
                        models.getDefaultProjectModels().getProjectInfoResults().get(3));
                BuilderResult projectInfo4 = CollectionUtils.getSingleElement(
                        models.getDefaultProjectModels().getProjectInfoResults().get(4));

                verifySerializationError(projectInfo1);
                verifySerializationError(projectInfo2);
                verifyDeserializationError(projectInfo3);
                verifyDeserializationError(projectInfo4);

                Object buildInfoOk = getSingleBuildResult(
                        models.getBuildInfoResults().get(0));
                assertTrue("The valid builder must succeed",
                        buildInfoOk.toString().startsWith(buildInfoPrefix));

                Object projectInfoOk = getSingleBuildResult(
                        models.getDefaultProjectModels().getProjectInfoResults().get(0));
                assertTrue("The valid builder must succeed",
                        projectInfoOk.toString().startsWith(projectInfoPrefix));
            }
        });
    }

    private static Map<Class<?>, Object> fetchBuiltInModels(
            ProjectConnection connection,
            Class<?>... modelClasses) throws IOException {

        Map<Object, List<GradleBuildInfoQuery<?>>> buildInfos = Collections.emptyMap();
        Map<Object, List<GradleProjectInfoQuery<?>>> projectInfos = Collections.emptyMap();
        Set<Class<?>> toolingModels = new HashSet<Class<?>>(Arrays.asList(modelClasses));

        GenericModelFetcher modelFetcher = new GenericModelFetcher(buildInfos, projectInfos, toolingModels);
        FetchedModels models = verifyNoError(modelFetcher.getModels(connection, defaultInit()));

        return models.getDefaultProjectModels().getToolingModels();
    }

    private void testBuiltInModels(String relativeProjectPath) throws IOException {
        final String projectPath = ":" + relativeProjectPath;

        runTestForSubProject(relativeProjectPath, new ProjectConnectionTask() {
            public void doTask(ProjectConnection connection) throws Exception {
                Class<?>[] models = new Class<?>[]{
                    EclipseProject.class,
                    IdeaProject.class,
                    GradleProject.class
                };

                Map<Class<?>, Object> fetched = fetchBuiltInModels(connection, models);

                HashSet<Class<?>> expected = new HashSet<Class<?>>(Arrays.asList(models));
                expected.removeAll(fetched.keySet());

                if (!expected.isEmpty()) {
                    fail("The following models are unavailable: "
                            + expected.toString().replace(",", ",\n"));
                }

                // FIXME: We don't test the GradleProject instance because
                //  Gradle returns the root project for each project. Is this a bug?

                EclipseProject eclipseProject = (EclipseProject)fetched.get(EclipseProject.class);
                assertEquals("EclipseProject must match the requested one",
                        projectPath, eclipseProject.getGradleProject().getPath());

                IdeaProject ideaProject = (IdeaProject)fetched.get(IdeaProject.class);
                GradleProject gradleProjectOfIdea = null;
                for (IdeaModule ideaModule: ideaProject.getModules()) {
                    if (projectPath.equals(ideaModule.getGradleProject().getPath())) {
                        gradleProjectOfIdea = ideaModule.getGradleProject();
                        break;
                    }
                }

                assertNotNull("IdeaProject must contain the requested module.", gradleProjectOfIdea);
            }
        });
    }

    @Test
    public void testBuiltInModels() throws IOException {
        for (String project: allProjects()) {
            testBuiltInModels(project);
        }
    }

    private static JavaOutputDirs defaultOutputOfSourceSet(
            File projectDir,
            String name) throws IOException {

        File classesDir = getSubPath(projectDir, "build", "classes", name);
        File resourcesDir = getSubPath(projectDir, "build", "resources", name);
        return new JavaOutputDirs(classesDir, resourcesDir, Collections.<File>emptySet());
    }

    private static JavaSourceGroup sourceGroupOfSourceSet(
            File projectDir,
            String name,
            JavaSourceGroupName sourceGroupName) throws IOException {

        File sourceRoot = getSubPath(projectDir, name, sourceGroupName.name().toLowerCase(Locale.US));
        return new JavaSourceGroup(sourceGroupName, Collections.singleton(sourceRoot));
    }

    private static JavaSourceSet.Builder defaultSourceSetBuilder(
            File projectDir,
            String name) throws IOException {

        JavaSourceSet.Builder sourceSet = new JavaSourceSet.Builder(
                name,
                defaultOutputOfSourceSet(projectDir, name));

        sourceSet.addSourceGroup(sourceGroupOfSourceSet(projectDir, name, JavaSourceGroupName.JAVA));
        sourceSet.addSourceGroup(sourceGroupOfSourceSet(projectDir, name, JavaSourceGroupName.RESOURCES));

        return sourceSet;
    }

    private static File projectDirByRelativeName(String relativeProjectName) throws IOException {
        return getSubProjectDir(testedProjectDir, relativeProjectName);
    }

    private static JavaSourceSet defaultJavaSourceSet(
            File projectDir,
            String name) throws IOException {

        JavaSourceSet.Builder builder = defaultSourceSetBuilder(projectDir, name);
        return builder.create();
    }

    private static JavaSourceSet defaultGroovySourceSet(
            File projectDir,
            String name) throws IOException {

        JavaSourceSet.Builder builder = defaultSourceSetBuilder(projectDir, name);
        builder.addSourceGroup(sourceGroupOfSourceSet(projectDir, name, JavaSourceGroupName.GROOVY));

        return builder.create();
    }

    private static JavaSourcesModel sourcesOfJavaProject(String relativeProjectName) throws IOException {
        File projectDir = projectDirByRelativeName(relativeProjectName);

        Collection<JavaSourceSet> sourceSets = new LinkedList<JavaSourceSet>();
        sourceSets.add(defaultJavaSourceSet(projectDir, "main"));
        sourceSets.add(defaultJavaSourceSet(projectDir, "test"));

        return new JavaSourcesModel(sourceSets);
    }

    private static JavaSourcesModel sourcesOfApp1() throws IOException {
        String relativeProjectName = "apps:app1";
        File projectDir = projectDirByRelativeName(relativeProjectName);

        Collection<JavaSourceSet> sourceSets = new LinkedList<JavaSourceSet>();
        sourceSets.add(defaultGroovySourceSet(projectDir, "main"));
        sourceSets.add(defaultGroovySourceSet(projectDir, "test"));

        return new JavaSourcesModel(sourceSets);
    }

    private static JavaSourcesModel sourcesOfApp2() throws IOException {
        return sourcesOfJavaProject("apps:app2");
    }

    private static JavaSourcesModel sourcesOfLib1() throws IOException {
        return sourcesOfJavaProject("libs:lib1");
    }

    private static JavaSourcesModel sourcesOfLib2() throws IOException {
        return sourcesOfJavaProject("libs:lib2");
    }

    private static JavaSourcesModel sourcesOfLib3() throws IOException {
        return sourcesOfJavaProject("libs:lib3");
    }

    private static JavaSourcesModel sourcesOfLib3Lib1() throws IOException {
        return sourcesOfJavaProject("libs:lib3:lib1");
    }

    private static JavaSourcesModel sourcesOfLib3Lib2() throws IOException {
        return sourcesOfJavaProject("libs:lib3:lib2");
    }
}
TOP

Related Classes of org.netbeans.gradle.model.java.MultiLevelJavaProjectTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.