org.eclipse.objectteams.otdt.ui.tests.refactoring.pullup.PullUpTests.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.objectteams.otdt.ui.tests.refactoring.pullup.PullUpTests.java

Source

/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 * 
 * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany,
 * for its Fraunhofer Institute and Computer Architecture and Software
 * Technology (FIRST), Berlin, Germany and Technical University Berlin,
 * Germany.
 * 
 * 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
 * $Id$
 * 
 * Please visit http://www.eclipse.org/objectteams for updates and contact.
 * 
 * Contributors:
 *      Fraunhofer FIRST - Initial API and implementation
 *      Technical University Berlin - Initial API and implementation
 **********************************************************************/
package org.eclipse.objectteams.otdt.ui.tests.refactoring.pullup;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import junit.framework.Test;
import junit.framework.TestSuite;

import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester;
import org.eclipse.jdt.internal.corext.refactoring.structure.PullUpRefactoringProcessor;
import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;
import org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring;
import org.eclipse.objectteams.otdt.ui.tests.refactoring.MySetup;
import org.eclipse.objectteams.otdt.ui.tests.refactoring.RefactoringTest;

/**
 * Example TestCase to practice testing for the diploma thesis.
 * 
 * @author Johannes Gebauer
 */
@SuppressWarnings("restriction")
public class PullUpTests extends RefactoringTest {
    private static final String REFACTORING_PATH = "PullUp/";

    public PullUpTests(String name) {
        super(name);
    }

    public static Test suite() {
        return new MySetup(new TestSuite(PullUpTests.class));
    }

    public static Test setUpTest(Test test) {
        return new MySetup(test);
    }

    protected String getRefactoringPath() {
        return REFACTORING_PATH;
    }

    private void setTargetClass(PullUpRefactoringProcessor processor, int targetClassIndex)
            throws JavaModelException {
        IType[] possibleClasses = getPossibleTargetClasses(processor);
        processor.setDestinationType(
                getPossibleTargetClasses(processor)[possibleClasses.length - 1 - targetClassIndex]);
    }

    private IType[] getPossibleTargetClasses(PullUpRefactoringProcessor processor) throws JavaModelException {
        return processor.getCandidateTypes(new RefactoringStatus(), new NullProgressMonitor());
    }

    private static IMethod[] getMethods(IMember[] members) {
        List<IJavaElement> l = Arrays.asList(JavaElementUtil.getElementsOfType(members, IJavaElement.METHOD));
        return l.toArray(new IMethod[l.size()]);
    }

    private static PullUpRefactoringProcessor createRefactoringProcessor(IMember[] methods)
            throws JavaModelException {
        IJavaProject project = null;
        if (methods != null && methods.length > 0)
            project = methods[0].getJavaProject();
        if (RefactoringAvailabilityTester.isPullUpAvailable(methods)) {
            PullUpRefactoringProcessor processor = new PullUpRefactoringProcessor(methods,
                    JavaPreferencesSettings.getCodeGenerationSettings(project));
            new ProcessorBasedRefactoring(processor);
            return processor;
        }
        return null;
    }

    /**
     * The <code>ICompilationUnit</code> containing the declaring type must be
     * at position 0.
     * 
     * @param fieldNames
     *            TODO
     */
    private void performPullUp_pass(String[] cuNames, String[] methodNames, String[][] signatures,
            String[] fieldNames, boolean deleteAllInSourceType, boolean deleteAllMatchingMethods,
            int targetClassIndex, String nameOfDeclaringType) throws Exception {
        performPullUp_pass(cuNames, methodNames, signatures, null, fieldNames, deleteAllInSourceType,
                deleteAllMatchingMethods, targetClassIndex, nameOfDeclaringType);
    }

    private void performPullUp_pass(String[] cuNames, String[] methodNames, String[][] signatures,
            boolean[] makeAbstract, String[] fieldNames, boolean deleteAllInSourceType,
            boolean deleteAllMatchingMethods, int targetClassIndex, String nameOfDeclaringType) throws Exception {
        performPullUp_pass(cuNames, methodNames, signatures, makeAbstract, fieldNames, deleteAllInSourceType,
                deleteAllMatchingMethods, targetClassIndex, nameOfDeclaringType, false/*replace*/);
    }

    private void performPullUp_pass(String[] cuNames, String[] methodNames, String[][] signatures,
            boolean[] makeAbstract, String[] fieldNames, boolean deleteAllInSourceType,
            boolean deleteAllMatchingMethods, int targetClassIndex, String nameOfDeclaringType, boolean replace)
            throws Exception {
        ICompilationUnit[] cus = createCUs(cuNames);
        try {

            IType declaringType = getType(cus[0], nameOfDeclaringType);
            IMethod[] methods = getMethods(declaringType, methodNames, signatures, makeAbstract, false);
            IField[] fields = getFields(declaringType, fieldNames);
            IMember[] members = merge(methods, fields);

            PullUpRefactoringProcessor processor = createRefactoringProcessor(members);
            if (makeAbstract != null)
                processor
                        .setAbstractMethods(getMethods(declaringType, methodNames, signatures, makeAbstract, true));
            Refactoring ref = processor.getRefactoring();

            assertTrue("activation", ref.checkInitialConditions(new NullProgressMonitor()).isOK());

            setTargetClass(processor, targetClassIndex);

            List<IMethod> methodList = new ArrayList<IMethod>();
            if (deleteAllInSourceType)
                methodList.addAll(Arrays.asList(methods));
            if (deleteAllMatchingMethods)
                methodList.addAll(
                        Arrays.asList(getMethods(processor.getMatchingElements(new NullProgressMonitor(), false))));
            if (!methodList.isEmpty())
                processor.setDeletedMethods(methodList.toArray(new IMethod[methodList.size()]));

            if (replace)
                processor.setReplace(true);

            RefactoringStatus checkInputResult = ref.checkFinalConditions(new NullProgressMonitor());
            assertTrue("precondition was supposed to pass", !checkInputResult.hasError());
            performChange(ref, false);

            for (int i = 0; i < cus.length; i++) {
                String expected = getFileContents(getOutputTestFileName(cuNames[i]));
                String actual = cus[i].getSource();
                assertEqualLines(expected, actual);
            }
        } finally {
            performDummySearch();
            for (int i = 0; i < cus.length; i++) {
                cus[i].delete(false, null);
            }

        }
    }

    /**
     * The <code>ICompilationUnit</code> containing the declaring type must be
     * at position 0.
     */
    private void performPullUp_warning(String[] cuNames, String[] methodNames, String[][] signatures,
            boolean deleteAllInSourceType, boolean deleteAllMatchingMethods, int targetClassIndex,
            String nameOfDeclaringType) throws Exception {
        ICompilationUnit[] cus = createCUs(cuNames);
        try {

            IType declaringType = getType(cus[0], nameOfDeclaringType);
            IMethod[] methods = getMethods(declaringType, methodNames, signatures);

            PullUpRefactoringProcessor processor = createRefactoringProcessor(methods);
            Refactoring ref = processor.getRefactoring();

            assertTrue("activation", ref.checkInitialConditions(new NullProgressMonitor()).isOK());

            setTargetClass(processor, targetClassIndex);

            if (deleteAllInSourceType)
                processor.setDeletedMethods(methods);
            if (deleteAllMatchingMethods)
                processor.setDeletedMethods(
                        getMethods(processor.getMatchingElements(new NullProgressMonitor(), false)));

            RefactoringStatus checkInputResult = ref.checkFinalConditions(new NullProgressMonitor());
            RefactoringStatusEntry[] initialConditionStatus = checkInputResult.getEntries();
            assertEquals("precondition was supposed to give a warning", RefactoringStatus.WARNING,
                    initialConditionStatus[0].getSeverity());
            assertEquals("precondition was supposed to give only one warning", initialConditionStatus.length, 1);

            performChange(ref, false);

            for (int i = 0; i < cus.length; i++) {
                String expected = getFileContents(getOutputTestFileName(cuNames[i]));
                String actual = cus[i].getSource();
                assertEqualLines(expected, actual);
            }
        } finally {
            performDummySearch();
            for (int i = 0; i < cus.length; i++) {
                cus[i].delete(false, null);
            }

        }
    }

    private void performPullUp_failing(String[] cuNames, String[] methodNames, String[][] signatures,
            String[] fieldNames, boolean deleteAllInSourceType, boolean deleteAllMatchingMethods,
            int targetClassIndex, String nameOfDeclaringType) throws Exception {
        performPullUp_failing(cuNames, methodNames, signatures, null, fieldNames, deleteAllInSourceType,
                deleteAllMatchingMethods, targetClassIndex, nameOfDeclaringType, null);
    }

    private void performPullUp_failing(String[] cuNames, String[] methodNames, String[][] signatures,
            boolean[] makeAbstract, String[] fieldNames, boolean deleteAllInSourceType,
            boolean deleteAllMatchingMethods, int targetClassIndex, String nameOfDeclaringType,
            String[] errorMessages) throws Exception {
        ICompilationUnit[] cus = createCUs(cuNames);
        try {

            IType declaringType = getType(cus[0], nameOfDeclaringType);
            IMethod[] methods = getMethods(declaringType, methodNames, signatures, makeAbstract, false);
            IField[] fields = getFields(declaringType, fieldNames);
            IMember[] members = merge(methods, fields);

            PullUpRefactoringProcessor processor = createRefactoringProcessor(members);
            if (makeAbstract != null)
                processor
                        .setAbstractMethods(getMethods(declaringType, methodNames, signatures, makeAbstract, true));
            Refactoring ref = processor.getRefactoring();

            setTargetClass(processor, targetClassIndex);

            if (deleteAllInSourceType)
                processor.setDeletedMethods(methods);
            if (deleteAllMatchingMethods)
                processor.setDeletedMethods(
                        getMethods(processor.getMatchingElements(new NullProgressMonitor(), false)));

            RefactoringStatus result = performRefactoring(ref);
            assertNotNull("precondition was supposed to fail.", result);
            assertTrue("precondition was supposed to fail.", !result.isOK());
            assertNotNull("precondition result is expected to contain an error.",
                    result.getEntryMatchingSeverity(RefactoringStatus.ERROR));
            if (errorMessages != null) {
                int i = 0;
                for (RefactoringStatusEntry entry : result.getEntries()) {
                    if (entry.isFatalError()) {
                        assertEquals("Wrong error message", errorMessages[i++], entry.getMessage());
                    }
                }
                assertEquals("Wrong number of error messages", errorMessages.length, i);
            }
        } finally {
            performDummySearch();
            for (int i = 0; i < cus.length; i++) {
                cus[i].delete(false, null);
            }

        }
    }

    /******* tests ******************/

    /* Pull up Method Tests */

    public void testPullUpBoundMethod() throws Exception {
        performPullUp_warning(new String[] { "B", "BSuper", "T" }, new String[] { "bm" },
                new String[][] { new String[0] }, true, false, 0, "B");
    }

    public void testPullUpCallinMethod() throws Exception {
        performPullUp_pass(new String[] { "T", "TSuper", "B" }, new String[] { "rm" },
                new String[][] { new String[0] }, new String[] {}, true, false, 0, "R");
    }

    public void testPullUpMethodToImplicitSuperclass() throws Exception {
        performPullUp_pass(new String[] { "T", "TSuper", "B" }, new String[] { "rm" },
                new String[][] { new String[0] }, new String[] {}, true, false, 0, "R");
    }

    public void testDeletionOfMatchingMethods() throws Exception {
        performPullUp_pass(new String[] { "T", "T2", "TSuper", "B" }, new String[] { "rm" },
                new String[][] { new String[0] }, new String[] {}, true, true, 0, "R");
    }

    public void testReferencingRoleInDeclaredLifting() throws Exception {
        performPullUp_failing(new String[] { "T", "TSuper", "B" }, new String[] { "m" },
                new String[][] { new String[] { "QB;" } }, new String[] {}, true, false, 0, "T");
    }

    public void testPulledUpMethodIsOverriddenInImplicitSubRole() throws Exception {
        performPullUp_failing(new String[] { "T1", "T2", "TSuper", }, new String[] { "m" },
                new String[][] { new String[0] }, new String[] {}, true, false, 0, "R");
    }

    public void testAmbiguityInExplicitRelatedRole1() throws Exception {
        performPullUp_failing(new String[] { "T", "B" }, new String[] { "m" }, new String[][] { new String[0] },
                new String[] {}, true, false, 0, "R1");
    }

    public void testAmbiguityInExplicitRelatedRole2() throws Exception {
        performPullUp_failing(new String[] { "T", "B" }, new String[] { "m" }, new String[][] { new String[0] },
                new String[] {}, true, false, 0, "R1");
    }

    public void testAmbiguityInImplicitRelatedRole1() throws Exception {
        performPullUp_failing(new String[] { "T1", "T2", "TSuper", "B" }, new String[] { "m" },
                new String[][] { new String[0] }, new String[] {}, true, false, 0, "R");
    }

    public void testAmbiguityInImplicitRelatedRole2() throws Exception {
        performPullUp_failing(new String[] { "T1", "T2", "TSuper", "B" }, new String[] { "m" },
                new String[][] { new String[0] }, new String[] {}, true, false, 0, "R");
    }

    public void testAmbiguityInBase1() throws Exception {
        performPullUp_failing(new String[] { "B2", "B1", "T" }, new String[] { "bm" },
                new String[][] { new String[0] }, new String[] {}, true, false, 0, "B2");
    }

    public void testAmbiguityInBase2() throws Exception {
        performPullUp_failing(new String[] { "B2", "B1", "T" }, new String[] { "bm" },
                new String[][] { new String[0] }, new String[] {}, true, false, 0, "B2");
    }

    public void testPullUpCallinIntoRegularClass() throws Exception {
        performPullUp_failing(new String[] { "T", "C" }, new String[] { "m" }, new String[][] { new String[0] },
                new String[] {}, true, false, 0, "R");
    }

    /* Pull up Field Tests */

    public void testPullUpAnchoredTypeField() throws Exception {
        performPullUp_failing(new String[] { "T2", "T1", "T3" }, new String[] {}, new String[][] { new String[0] },
                new String[] { "extern" }, true, false, 0, "T2");
    }

    public void testPulledUpFieldWillBeShadowed() throws Exception {
        performPullUp_failing(new String[] { "T2", "T1", "T3" }, new String[] {}, new String[][] { new String[0] },
                new String[] { "f" }, true, false, 0, "Role");
    }

    public void testPullUpCalloutFieldInBase() throws Exception {
        performPullUp_pass(new String[] { "B1", "B2", "T" }, new String[] {}, new String[][] { new String[0] },
                new String[] { "f" }, true, false, 0, "B1");
    }

    public void testPullUpFieldToImplicitSuperclass() throws Exception {
        performPullUp_pass(new String[] { "T", "TSuper" }, new String[] {}, new String[][] { new String[0] },
                new String[] { "f" }, true, false, 0, "R");
    }

    // Bug 374841 - [refactoring] pull up does not work among (nested) roles
    public void testPullUpWithReferenceToCallout1() throws Exception {
        // without pull-up of getS1/getS2 we cannot succeed:
        performPullUp_failing(new String[] { "T", "B" }, new String[] { "foo" }, new String[][] { new String[0] },
                new String[0], true, true, 0, "RSub");
    }

    // Bug 386587 - [refactoring] pull-up refactoring cannot handle callout bindings
    public void testPullUpWithReferenceToCallout2() throws Exception {
        performPullUp_pass(new String[] { "T", "B" }, new String[] { "foo", "getS1", "getS2" },
                new String[][] { new String[0], new String[0], new String[0] }, new boolean[] { false, true, true },
                new String[0], true, true, 0, "RSub", true /*replace*/);
    }

    // Bug 386814 - [refactoring] pull-up should distinguish callouts that can be pull-up vs. abstract decl.
    public void testPullUpCallout1() throws Exception {
        performPullUp_failing(new String[] { "T", "B" }, new String[] { "foo", "getS1", "getS2" },
                new String[][] { new String[0], new String[0], new String[0] },
                new boolean[] { false, false, true }, // true pull up of callout not possible 
                new String[0], true, true, 0, "RSub", new String[] {
                        "The callout binding 'getS1() -> String s' can only be moved to a bound role (OTJLD \u00A73.1.(a))." });
    }

    // Bug 386814 - [refactoring] pull-up should distinguish callouts that can be pull-up vs. abstract decl.
    public void testPullUpCallout2() throws Exception {
        performPullUp_pass(new String[] { "T", "B0", "B1", "B2" }, new String[] { "foo", "getS1", "getS2" },
                new String[][] { new String[0], new String[0], new String[0] },
                new boolean[] { false, false, false }, // true pull up of callout 
                new String[0], true, true, 0, "RSub");
    }

    // Bug 386814 - [refactoring] pull-up should distinguish callouts that can be pull-up vs. abstract decl.
    public void testPullUpCallout3() throws Exception {
        performPullUp_failing(new String[] { "T", "B0", "B1", "B2" }, new String[] { "foo", "getS1", "getS2" },
                new String[][] { new String[0], new String[0], new String[0] },
                new boolean[] { false, false, false }, // true pull up of callout, which are NOT available in super base (B1)
                new String[0], true, true, 0, "RSub",
                new String[] {
                        "The callout binding 'getS1() -> String s' cannot be moved to class 'RSuper', because the the bound base member 's' will not be accessible after refactoring (OTJLD \u00A73.1.(a)).",
                        "The callout binding 'getS2() -> getS()' cannot be moved to class 'RSuper', because the the bound base member 'getS' will not be accessible after refactoring (OTJLD \u00A73.1.(a))." });
    }
}