| /******************************************************************************* |
| * Copyright (c) 2019 Marco Stornelli |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| *******************************************************************************/ |
| package org.eclipse.cdt.ui.tests.refactoring.overridemethods; |
| |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; |
| import org.eclipse.cdt.internal.ui.refactoring.CRefactoring; |
| import org.eclipse.cdt.internal.ui.refactoring.overridemethods.Method; |
| import org.eclipse.cdt.internal.ui.refactoring.overridemethods.OverrideMethodsRefactoring; |
| import org.eclipse.cdt.ui.tests.refactoring.RefactoringTestBase; |
| |
| import junit.framework.Test; |
| |
| /** |
| * Tests for override methods |
| */ |
| public class OverrideMethodsRefactoringTest extends RefactoringTestBase { |
| |
| private String[] selectedMethods; |
| private OverrideMethodsRefactoring refactoring; |
| private boolean addOverride = false; |
| private boolean preserveVirtual = true; |
| |
| public OverrideMethodsRefactoringTest() { |
| super(); |
| } |
| |
| public OverrideMethodsRefactoringTest(String name) { |
| super(name); |
| } |
| |
| public static Test suite() { |
| return suite(OverrideMethodsRefactoringTest.class); |
| } |
| |
| @Override |
| protected CRefactoring createRefactoring() { |
| refactoring = new OverrideMethodsRefactoring(getSelectedTranslationUnit(), getSelection(), getCProject()); |
| return refactoring; |
| } |
| |
| @Override |
| protected void simulateUserInput() { |
| if (selectedMethods != null) { |
| Map<ICPPClassType, List<Method>> map = refactoring.getMethodContainer().getInitialInput(); |
| for (Map.Entry<ICPPClassType, List<Method>> entry : map.entrySet()) { |
| List<Method> methods = entry.getValue(); |
| for (Method m : methods) { |
| for (String name : selectedMethods) { |
| if (m.toString().equals(name)) |
| refactoring.getPrintData().addMethod(m); |
| } |
| } |
| } |
| } |
| refactoring.getOptions().setAddOverride(addOverride); |
| refactoring.getOptions().setPreserveVirtual(preserveVirtual); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // virtual void baseFunc() const; |
| //}; |
| // |
| //inline void X::baseFunc() const { |
| //} |
| public void testWithHeaderOnly() throws Exception { |
| selectedMethods = new String[] { "baseFunc()const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // virtual void baseFunc() const; |
| //}; |
| |
| //A.cpp |
| //#include "A.h" |
| //==================== |
| //#include "A.h" |
| // |
| //void X::baseFunc() const { |
| //} |
| public void testWithHeaderAndSource() throws Exception { |
| selectedMethods = new String[] { "baseFunc()const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //namespace FIRST { |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc(Base *ptr) const = 0; |
| //}; |
| //}; |
| //namespace SECOND { |
| //class X: public FIRST::Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //}; |
| //==================== |
| //namespace FIRST { |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc(Base *ptr) const = 0; |
| //}; |
| //}; |
| //namespace SECOND { |
| //class X: public FIRST::Base { |
| //public: |
| // X(); |
| // virtual void baseFunc(FIRST::Base *ptr) const; |
| //}; |
| //}; |
| |
| //A.cpp |
| //#include "A.h" |
| //==================== |
| //#include "A.h" |
| // |
| //void SECOND::X::baseFunc(FIRST::Base *ptr) const { |
| //} |
| public void testWithMixedNamespaceHeaderAndSource() throws Exception { |
| selectedMethods = new String[] { "baseFunc(FIRST::Base *)const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // void baseFunc() const; |
| //}; |
| // |
| //inline void X::baseFunc() const { |
| //} |
| public void testIgnoringVirtual() throws Exception { |
| preserveVirtual = false; |
| selectedMethods = new String[] { "baseFunc()const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // virtual void baseFunc() const override; |
| //}; |
| // |
| //inline void X::baseFunc() const { |
| //} |
| public void testAddingOverrideVirtual() throws Exception { |
| addOverride = true; |
| selectedMethods = new String[] { "baseFunc()const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //template<class T> |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //template<class T> |
| //class X: public Base { |
| //public: |
| // X(); |
| // virtual void baseFunc() const; |
| //}; |
| // |
| //template<class T> |
| //inline void X<T>::baseFunc() const { |
| //} |
| public void testWithTemplateClass() throws Exception { |
| selectedMethods = new String[] { "baseFunc()const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //template<class T> |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc(T *t) const = 0; |
| //}; |
| //class X: public Base<int> { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //template<class T> |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc(T *t) const = 0; |
| //}; |
| //class X: public Base<int> { |
| //public: |
| // X(); |
| // virtual void baseFunc(int *t) const; |
| //}; |
| |
| //A.cpp |
| //#include "A.h" |
| //==================== |
| //#include "A.h" |
| // |
| //void X::baseFunc(int *t) const { |
| //} |
| public void testWithTemplateBaseClass() throws Exception { |
| selectedMethods = new String[] { "baseFunc(int *) {#0,0: int}" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X { |
| //public: |
| // X(); |
| // class Internal: public Base { |
| // public: |
| // /*$*//*$$*/ |
| // }; |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X { |
| //public: |
| // X(); |
| // class Internal: public Base { |
| // public: |
| // virtual void baseFunc() const; |
| // }; |
| //}; |
| |
| //A.cpp |
| //#include "A.h" |
| //==================== |
| //#include "A.h" |
| // |
| //void X::Internal::baseFunc() const { |
| //} |
| public void testWithNestedClass() throws Exception { |
| selectedMethods = new String[] { "baseFunc()const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| //}; |
| ///*$*//*$$*/ |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| //}; |
| public void testWithNoSelection() throws Exception { |
| selectedMethods = new String[] { "baseFunc()const" }; |
| assertRefactoringFailure(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // void baseFunc() const; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| ///*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // void baseFunc() const; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| //}; |
| public void testWithNoMethods() throws Exception { |
| selectedMethods = new String[] { "baseFunc()const" }; |
| assertRefactoringFailure(); |
| } |
| |
| //A.h |
| //class X { |
| //public: |
| // X(); |
| ///*$*//*$$*/ |
| //}; |
| //==================== |
| //class X { |
| //public: |
| // X(); |
| //}; |
| public void testWithNoBaseClass() throws Exception { |
| assertRefactoringFailure(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const throw (int) = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const throw (int) = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // virtual void baseFunc() const throw (int); |
| //}; |
| // |
| //inline void X::baseFunc() const throw (int) { |
| //} |
| public void testWithThrowNoEmpty() throws Exception { |
| selectedMethods = new String[] { "baseFunc()const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const throw () = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const throw () = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // virtual void baseFunc() const throw (); |
| //}; |
| // |
| //inline void X::baseFunc() const throw () { |
| //} |
| public void testWithThrowEmpty() throws Exception { |
| selectedMethods = new String[] { "baseFunc()const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const noexcept = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const noexcept = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // virtual void baseFunc() const noexcept; |
| //}; |
| // |
| //inline void X::baseFunc() const noexcept { |
| //} |
| public void testWithNoExcept() throws Exception { |
| selectedMethods = new String[] { "baseFunc()const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc1() const = 0; |
| // virtual void baseFunc2() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc1() const = 0; |
| // virtual void baseFunc2() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // virtual void baseFunc2() const; |
| // virtual void baseFunc1() const; |
| //}; |
| // |
| //inline void X::baseFunc2() const { |
| //} |
| // |
| //inline void X::baseFunc1() const { |
| //} |
| public void testWithMultipleMethods() throws Exception { |
| selectedMethods = new String[] { "baseFunc1()const", "baseFunc2()const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() && = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() && = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // virtual void baseFunc() &&; |
| //}; |
| // |
| //inline void X::baseFunc() && { |
| //} |
| public void testWithRefQualifier() throws Exception { |
| selectedMethods = new String[] { "baseFunc()&&" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void* baseFunc(void *ptr) const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void* baseFunc(void *ptr) const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // virtual void* baseFunc(void *ptr) const; |
| //}; |
| |
| //A.cpp |
| //#include "A.h" |
| //==================== |
| //#include "A.h" |
| // |
| //void* X::baseFunc(void *ptr) const { |
| //} |
| public void testWithPointers() throws Exception { |
| selectedMethods = new String[] { "baseFunc(void *)const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void* baseFunc(void *ptr) const = 0, method2(); |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void* baseFunc(void *ptr) const = 0, method2(); |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // virtual void* baseFunc(void *ptr) const; |
| //}; |
| |
| //A.cpp |
| //#include "A.h" |
| //==================== |
| //#include "A.h" |
| // |
| //void* X::baseFunc(void *ptr) const { |
| //} |
| public void testWithMultipleMethodsOnSameLine() throws Exception { |
| selectedMethods = new String[] { "baseFunc(void *)const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const { |
| // } |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //==================== |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const { |
| // } |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // virtual void baseFunc() const; |
| //}; |
| // |
| //inline void X::baseFunc() const { |
| //} |
| public void testWithHeaderOnlyImpl_Bug548138() throws Exception { |
| selectedMethods = new String[] { "baseFunc()const" }; |
| assertRefactoringSuccess(); |
| } |
| |
| //A.h |
| //namespace Bar { |
| //namespace Foo { |
| //namespace Baz { |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // /*$*//*$$*/ |
| //}; |
| //} |
| //} |
| //} |
| //==================== |
| //namespace Bar { |
| //namespace Foo { |
| //namespace Baz { |
| //class Base { |
| //public: |
| // virtual ~Base(); |
| // virtual void baseFunc() const = 0; |
| //}; |
| //class X: public Base { |
| //public: |
| // X(); |
| // virtual void baseFunc() const; |
| //}; |
| //} |
| //} |
| //} |
| |
| //A.cpp |
| //#include "A.h" |
| // |
| //namespace Bar { |
| //namespace Foo { |
| //namespace Baz { |
| //} |
| //} |
| //} |
| //==================== |
| //#include "A.h" |
| // |
| //namespace Bar { |
| //namespace Foo { |
| //namespace Baz { |
| // |
| //void X::baseFunc() const { |
| //} |
| // |
| //} |
| //} |
| //} |
| public void testWithHeaderAndSource_Bug562292() throws Exception { |
| selectedMethods = new String[] { "baseFunc()const" }; |
| assertRefactoringSuccess(); |
| } |
| } |