com.google.gwt.eclipse.core.compile.GWTCompileRunnerTest.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.eclipse.core.compile.GWTCompileRunnerTest.java

Source

/*******************************************************************************
 * Copyright 2011 Google Inc. All Rights Reserved.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * 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.google.gwt.eclipse.core.compile;

import com.google.gdt.eclipse.core.JavaProjectUtilities;
import com.google.gdt.eclipse.core.ResourceUtils;
import com.google.gdt.eclipse.core.projects.ProjectUtilities;
import com.google.gwt.eclipse.core.nature.GWTNature;

import junit.framework.TestCase;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.ClasspathEntry;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Tests the GWTCompileRunner.
 */
@SuppressWarnings("restriction")
public class GWTCompileRunnerTest extends TestCase {

    private static final String JAVA_PROJECT_A_NAME = "projectA";
    private static final String JAVA_PROJECT_B_NAME = "projectB";
    private static final String SECONDARY_SRC_DIR_NAME = "secondary-src-dir";
    private static final String SRC_DIR_NAME = "src";

    /**
     * Create a library entry and add it to the raw classpath.
     */
    private static void addAndCreateFolderLibraryEntry(IJavaProject javaProject, String folderName)
            throws CoreException, UnsupportedEncodingException {
        IFolder projLibFolder = javaProject.getProject().getFolder(folderName);
        ResourceUtils.createFolderStructure(javaProject.getProject(), projLibFolder.getProjectRelativePath());
        JavaProjectUtilities.addRawClassPathEntry(javaProject,
                JavaCore.newLibraryEntry(projLibFolder.getFullPath(), null, null, true /* exported */));
    }

    /**
     * Create a JAR library entry and add it to the raw classpath.
     * <p>
     * This ensures a file exist at the target library path, but no guarantees on
     * its contents or its validity as a JAR.
     */
    private static void addAndCreateJarLibraryEntry(IJavaProject javaProject, IPath projectRelativeLibraryPath)
            throws CoreException, UnsupportedEncodingException {
        IFile lib = javaProject.getProject().getFile(projectRelativeLibraryPath);
        // Create the parent dirs and a dummy file for the library
        ResourceUtils.createFolderStructure(javaProject.getProject(),
                projectRelativeLibraryPath.removeLastSegments(1));
        ResourceUtils.createFile(lib.getFullPath(), "");
        JavaProjectUtilities.addRawClassPathEntry(javaProject,
                JavaCore.newLibraryEntry(lib.getFullPath(), null, null, true /* exported */));
    }

    /**
     * Create a source entry (including the dir structure) and add it to the raw
     * classpath.
     * 
     * @param javaProject The Java project that receives the source entry
     * @param directoryName The source directory name
     * @param outputDirectoryName The optional output location of this source
     *          directory. Pass null for the default output location.
     */
    private static void addAndCreateSourceEntry(IJavaProject javaProject, String directoryName,
            String outputDirectoryName) throws CoreException {
        IFolder srcFolder = javaProject.getProject().getFolder(directoryName);
        ResourceUtils.createFolderStructure(javaProject.getProject(), srcFolder.getProjectRelativePath());

        IPath workspaceRelOutPath = null;
        if (outputDirectoryName != null) {
            // Ensure output directory exists
            IFolder outFolder = javaProject.getProject().getFolder(outputDirectoryName);
            ResourceUtils.createFolderStructure(javaProject.getProject(), outFolder.getProjectRelativePath());
            workspaceRelOutPath = outFolder.getFullPath();
        }

        JavaProjectUtilities.addRawClassPathEntry(javaProject,
                JavaCore.newSourceEntry(srcFolder.getFullPath(), ClasspathEntry.EXCLUDE_NONE, workspaceRelOutPath));
    }

    /**
     * Gets a File instance for the specified path.
     */
    private static File getFile(IProject project, String projectRelativePath) {
        return project.getLocation().append(projectRelativePath).toFile();
    }

    /**
     * Gets a list of File from a list of resolved IRuntimeClasspathEntry.
     * 
     */
    private static List<File> getListOfFiles(List<IRuntimeClasspathEntry> classpathEntries) {
        List<File> files = new ArrayList<File>();
        for (IRuntimeClasspathEntry classpathEntry : classpathEntries) {
            files.add(new File(classpathEntry.getLocation()));
        }

        return files;
    }

    /**
     * Gets a File pointing to the output of the given Java project.
     */
    private static File getOutputOfProject(IJavaProject javaProject) throws CoreException {
        return ResourceUtils.resolveToAbsoluteFileSystemPath(javaProject.getOutputLocation()).toFile();
    }

    /** A simple project with only the JRE in the classpath (by default). */
    private IJavaProject javaProjectA;

    /** A simple project with only the JRE in the classpath (by default). */
    private IJavaProject javaProjectB;

    /**
     * Tests computing the classpath for dependent projects.
     */
    public void testComputeClasspathForDependentProject() throws CoreException {
        addAndCreateSourceEntry(javaProjectA, SRC_DIR_NAME, null);
        addAndCreateSourceEntry(javaProjectB, SRC_DIR_NAME, null);

        // Make project A dependent on project B
        JavaProjectUtilities.addRawClassPathEntry(javaProjectA,
                JavaCore.newProjectEntry(javaProjectB.getProject().getFullPath(), true));

        // Get the computed classpath
        List<File> actualCp = getListOfFiles(GWTCompileRunner.computeClasspath(javaProjectA));

        // Ensure the paths and ordering are all the same
        List<File> expectedCp = new ArrayList<File>();

        // Source of project A
        expectedCp.add(getFile(javaProjectA.getProject(), SRC_DIR_NAME));

        // Source of project B
        expectedCp.add(getFile(javaProjectB.getProject(), SRC_DIR_NAME));

        // Output of project A
        expectedCp.add(getOutputOfProject(javaProjectA));

        // Output of project B
        expectedCp.add(getOutputOfProject(javaProjectB));

        assertEquals(expectedCp, actualCp);
    }

    /**
     * Tests that the computed classpath does not contain the JRE.
     */
    public void testComputeClasspathForJre() throws CoreException {
        // The raw classpath includes the JRE
        assertEquals(1, javaProjectA.getRawClasspath().length);

        // Get the computed classpath
        List<File> actualCp = getListOfFiles(GWTCompileRunner.computeClasspath(javaProjectA));

        // The GWT compiler classpath should not contain the JRE
        assertEquals(0, actualCp.size());
    }

    /**
     * Tests computing the classpath for libraries (both a folder library and a
     * JAR).
     */
    public void testComputeClasspathForLibrary() throws CoreException, UnsupportedEncodingException {
        final IPath projectRelativeJarPath = new Path("lib/test.jar");
        // Tests the CPE_LIBRARY for folders (that usually contain classes)
        final String folderName = "folder-library";

        addAndCreateJarLibraryEntry(javaProjectA, projectRelativeJarPath);
        addAndCreateFolderLibraryEntry(javaProjectA, folderName);

        // Get the computed classpath
        List<File> actualCp = getListOfFiles(GWTCompileRunner.computeClasspath(javaProjectA));

        // Ensure the paths and ordering are all the same
        List<File> expectedCp = new ArrayList<File>();

        // JAR
        expectedCp.add(getFile(javaProjectA.getProject(), projectRelativeJarPath.toOSString()));

        // Folder
        expectedCp.add(getFile(javaProjectA.getProject(), folderName));

        assertEquals(expectedCp, actualCp);
    }

    /**
     * Tests computing the classpath for a project with multiple source
     * directories.
     */
    public void testComputeClasspathForMultipleSources() throws CoreException {
        addAndCreateSourceEntry(javaProjectA, SRC_DIR_NAME, null);
        addAndCreateSourceEntry(javaProjectA, SECONDARY_SRC_DIR_NAME, null);

        // Get the computed classpath
        List<File> actualCp = getListOfFiles(GWTCompileRunner.computeClasspath(javaProjectA));

        // Ensure the paths and ordering are all the same
        List<File> expectedCp = new ArrayList<File>();

        // Check that it contains both source dirs
        expectedCp.add(getFile(javaProjectA.getProject(), SRC_DIR_NAME));
        expectedCp.add(getFile(javaProjectA.getProject(), SECONDARY_SRC_DIR_NAME));

        // Check that it contains the output dir of A
        expectedCp.add(getOutputOfProject(javaProjectA));

        assertEquals(expectedCp, actualCp);
    }

    /**
     * Tests computing the classpath for a project with a dependency project that
     * all have multiple source directories and each having a specific output
     * directory.
     */
    public void testComputeClasspathForProjectsWithMultipleSourcesAndSpecificOutputs() throws CoreException {
        final String sourceOutDirName = "srcOut";
        final String secondarySourceOutDirName = "secondarySrcOut";

        // Create source dirs and specific outputs for A
        addAndCreateSourceEntry(javaProjectA, SRC_DIR_NAME, sourceOutDirName);
        addAndCreateSourceEntry(javaProjectA, SECONDARY_SRC_DIR_NAME, secondarySourceOutDirName);

        // Create source dirs and specific outputs for B
        addAndCreateSourceEntry(javaProjectB, SRC_DIR_NAME, sourceOutDirName);
        addAndCreateSourceEntry(javaProjectB, SECONDARY_SRC_DIR_NAME, secondarySourceOutDirName);

        // Add A depends on B
        JavaProjectUtilities.addRawClassPathEntry(javaProjectA,
                JavaCore.newProjectEntry(javaProjectB.getProject().getFullPath(), true));

        // Get the computed classpath
        List<File> actualCp = getListOfFiles(GWTCompileRunner.computeClasspath(javaProjectA));

        // Ensure the paths and ordering are all the same
        List<File> expectedCp = new ArrayList<File>();

        // Check that it contains both source dirs for A
        expectedCp.add(getFile(javaProjectA.getProject(), SRC_DIR_NAME));
        expectedCp.add(getFile(javaProjectA.getProject(), SECONDARY_SRC_DIR_NAME));

        // Check that it contains both source dirs for B
        expectedCp.add(getFile(javaProjectB.getProject(), SRC_DIR_NAME));
        expectedCp.add(getFile(javaProjectB.getProject(), SECONDARY_SRC_DIR_NAME));

        // Check that it contains both output dirs for A
        IPath projPath = javaProjectA.getProject().getFullPath();
        expectedCp.add(ResourceUtils.resolveToAbsoluteFileSystemPath(projPath.append(sourceOutDirName)).toFile());
        expectedCp.add(
                ResourceUtils.resolveToAbsoluteFileSystemPath(projPath.append(secondarySourceOutDirName)).toFile());

        // Check that the default output directory for A is there
        expectedCp.add(getOutputOfProject(javaProjectA));

        // Check that it contains both output dirs for B
        IPath projBPath = javaProjectB.getProject().getFullPath();
        expectedCp.add(ResourceUtils.resolveToAbsoluteFileSystemPath(projBPath.append(sourceOutDirName)).toFile());
        expectedCp.add(ResourceUtils.resolveToAbsoluteFileSystemPath(projBPath.append(secondarySourceOutDirName))
                .toFile());

        // Check that the default output directory for B is there
        expectedCp.add(getOutputOfProject(javaProjectB));

        assertEquals(expectedCp, actualCp);
    }

    /**
     * Tests computing the classpath for a simple project (one source, one
     * output).
     */
    public void testComputeClasspathForSimpleProject() throws CoreException {
        addAndCreateSourceEntry(javaProjectA, SRC_DIR_NAME, null);

        // Get the computed classpath
        List<File> actualCp = getListOfFiles(GWTCompileRunner.computeClasspath(javaProjectA));

        // Ensure the paths and ordering are all the same
        List<File> expectedCp = new ArrayList<File>();

        // Check that it contains the source dir
        expectedCp.add(getFile(javaProjectA.getProject(), SRC_DIR_NAME));

        // Check that it contains the output dir
        expectedCp.add(getOutputOfProject(javaProjectA));

        assertEquals(expectedCp, actualCp);
    }

    /**
     * Tests variable support when computing classpaths. 
     */
    public void testComputeClasspathForVariables() throws CoreException, IOException {
        // Create the classpath variable
        Random rand = new Random();
        String varName = null;
        while (varName == null) {
            String curVarName = this.getName() + rand.nextInt();
            if (JavaCore.getClasspathVariable(curVarName) == null) {
                varName = curVarName;
            }
        }

        File systemTempFile = File.createTempFile(this.getName(), ".temp");
        JavaCore.setClasspathVariable(varName, Path.fromOSString(systemTempFile.getAbsolutePath()),
                new NullProgressMonitor());

        try {
            // Create a variable entry and add it to the raw classpath
            JavaProjectUtilities.addRawClassPathEntry(javaProjectA,
                    JavaCore.newVariableEntry(new Path(varName), null, null, true));

            // Get the computed classpath
            List<File> actualCp = getListOfFiles(GWTCompileRunner.computeClasspath(javaProjectA));

            // Ensure the paths and ordering are all the same
            List<File> expectedCp = new ArrayList<File>();
            expectedCp.add(systemTempFile);

            assertEquals(expectedCp, actualCp);
        } finally {
            JavaCore.removeClasspathVariable(varName, new NullProgressMonitor());
        }
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        javaProjectA = JavaProjectUtilities.createJavaProject(JAVA_PROJECT_A_NAME);
        GWTNature.addNatureToProject(javaProjectA.getProject());

        javaProjectB = JavaProjectUtilities.createJavaProject(JAVA_PROJECT_B_NAME);
        GWTNature.addNatureToProject(javaProjectB.getProject());
    }

    @Override
    protected void tearDown() throws Exception {
        super.tearDown();

        ProjectUtilities.deleteProject(javaProjectA.getElementName());
        ProjectUtilities.deleteProject(javaProjectB.getElementName());
    }

}