blob: d99cc6daf1315849a426cb99637f8d5ee1a44238 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2016 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* 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
*
* Contributors:
* Institute for Software - initial API and implementation
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
*******************************************************************************/
package org.eclipse.cdt.ui.tests.refactoring.extractconstant;
import junit.framework.Test;
import java.util.Arrays;
import java.util.function.Predicate;
import org.eclipse.core.runtime.CoreException;
import org.junit.Before;
import org.eclipse.cdt.ui.tests.refactoring.RefactoringTestBase;
import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
import org.eclipse.cdt.internal.ui.refactoring.CRefactoringContext;
import org.eclipse.cdt.internal.ui.refactoring.extractconstant.ExtractConstantInfo;
import org.eclipse.cdt.internal.ui.refactoring.extractconstant.ExtractConstantRefactoring;
import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
/**
* Tests for Extract Constant refactoring.
*/
public class ExtractConstantRefactoringTest extends RefactoringTestBase {
private String extractedConstantName;
private VisibilityEnum visibility;
private ExtractConstantRefactoring refactoring;
public ExtractConstantRefactoringTest() {
super();
}
public ExtractConstantRefactoringTest(String name) {
super(name);
}
public static Test suite() {
return suite(ExtractConstantRefactoringTest.class);
}
@Before
public void setUp() throws Exception {
extractedConstantName = "EXTRACTED";
visibility = VisibilityEnum.v_private;
super.setUp();
}
@Override
protected CRefactoring createRefactoring() {
refactoring = new ExtractConstantRefactoring(getSelectedTranslationUnit(), getSelection(),
getCProject());
return refactoring;
}
@Override
protected void simulateUserInput() {
ExtractConstantInfo info = refactoring.getRefactoringInfo();
info.setName(extractedConstantName);
info.setVisibility(visibility);
}
//A.h
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
// void bar();
//};
//
//#endif /*A_H_*/
//====================
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
// void bar();
//
//private:
// static const int EXTRACTED = 42;
//};
//
//#endif /*A_H_*/
//A.cpp
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return /*$*/42/*$$*/; //Hello
//}
//
//void A::bar() {
// int a = 42;
// int b = 42;
//}
//====================
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return EXTRACTED; //Hello
//}
//
//void A::bar() {
// int a = EXTRACTED;
// int b = EXTRACTED;
//}
public void testExtractConstantInt() throws Exception {
assertRefactoringSuccess();
}
//A.h
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
// void bar();
//};
//
//#endif /*A_H_*/
//====================
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
// void bar();
//
//private:
// static const int EXTRACTED = 42;
//};
//
//#endif /*A_H_*/
//A.cpp
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// //Hello
// return /*$*/42/*$$*/;
//}
//
//void A::bar() {
// int a = 42;
// int b = 42;
//}
//====================
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// //Hello
// return EXTRACTED;
//}
//
//void A::bar() {
// int a = EXTRACTED;
// int b = EXTRACTED;
//}
public void testExtractConstantInt2() throws Exception {
assertRefactoringSuccess();
}
//A.h
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// float foo();
// void bar();
//};
//
//#endif /*A_H_*/
//====================
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// float foo();
// void bar();
//
//private:
// static const float EXTRACTED = 42.0f;
//};
//
//#endif /*A_H_*/
//A.cpp
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//float A::foo() {
// return /*$*/42.0f/*$$*/;
//}
//
//void A::bar() {
// float a = 42.0f;
// float b = 42.0f;
//}
//====================
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//float A::foo() {
// return EXTRACTED;
//}
//
//void A::bar() {
// float a = EXTRACTED;
// float b = EXTRACTED;
//}
public void testExtractConstantFloat() throws Exception {
assertRefactoringSuccess();
}
//A.h
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// double foo();
// void bar();
//};
//
//#endif /*A_H_*/
//====================
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// double foo();
// void bar();
//
//private:
// static const double EXTRACTED = 42.0;
//};
//
//#endif /*A_H_*/
//A.cpp
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//double A::foo() {
// return /*$*/42.0/*$$*/;
//}
//
//void A::bar() {
// double a = 42.0;
// double b = 42.0;
//}
//====================
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//double A::foo() {
// return EXTRACTED;
//}
//
//void A::bar() {
// double a = EXTRACTED;
// double b = EXTRACTED;
//}
public void testExtractConstantDouble() throws Exception {
assertRefactoringSuccess();
}
//A.h
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
// static const int a = 42;
//};
//
//#endif /*A_H_*/
//====================
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
// static const int a = 42;
//};
//
//#endif /*A_H_*/
//A.cpp
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return 42;
//}
//
//int bar() {
// return /*$*/42/*$$*/;
//}
//====================
//#include "A.h"
//
//namespace {
//
//const int EXTRACTED = 42;
//
//}
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return EXTRACTED;
//}
//
//int bar() {
// return EXTRACTED;
//}
public void testExtractConstantStaticInt() throws Exception {
assertRefactoringSuccess();
}
//A.h
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
//};
//
//#endif /*A_H_*/
//====================
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
//
//protected:
// static const int EXTRACTED = 42;
//};
//
//#endif /*A_H_*/
//A.cpp
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return /*$*/42/*$$*/;
//}
//====================
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return EXTRACTED;
//}
public void testReplaceNumberProtected() throws Exception {
visibility = VisibilityEnum.v_protected;
assertRefactoringSuccess();
}
//A.h
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
//};
//
//#endif /*A_H_*/
//====================
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
//
//private:
// static const int EXTRACTED = 42;
//};
//
//#endif /*A_H_*/
//A.cpp
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return /*$*/42/*$$*/;
//}
//====================
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return EXTRACTED;
//}
public void testReplaceNumberPrivate() throws Exception {
assertRefactoringSuccess();
}
//A.h
//class X {
// void method() {
// int a = /*$*/42/*$$*/;
// }
//};
//====================
//class X {
//public:
// static const int EXTRACTED = 42;
//
//private:
// void method() {
// int a = EXTRACTED;
// }
//};
public void testExtractConstantFromInlinedMethod_Bug246062() throws Exception {
visibility = VisibilityEnum.v_public;
assertRefactoringSuccess();
}
//A.h
//class X {
// void method() {
// char* a = /*$*/"sometext"/*$$*/;
// }
//
// void method2() {
// const char* b = "sometext";
// }
//};
//====================
//class X {
// void method() {
// char* a = EXTRACTED;
// }
//
// void method2() {
// const char* b = EXTRACTED;
// }
//
// static const char* EXTRACTED = "sometext";
//};
public void testString() throws Exception {
assertRefactoringSuccess();
}
//A.h
//class X {
// void method() {
// wchar_t* a = /*$*/L"sometext"/*$$*/;
// }
//
// void method2() {
// const wchar_t* b = L"sometext";
// const char* c = "sometext";
// }
//};
//====================
//class X {
// void method() {
// wchar_t* a = EXTRACTED;
// }
//
// void method2() {
// const wchar_t* b = EXTRACTED;
// const char* c = "sometext";
// }
//
// static const wchar_t* EXTRACTED = L"sometext";
//};
public void testExtractConstantWideString() throws Exception {
assertRefactoringSuccess();
}
//A.h
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
// void bar();
//};
//
//#endif /*A_H_*/
//====================
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
// void bar();
//
// static const int EXTRACTED = 42;
//};
//
//#endif /*A_H_*/
//A.cpp
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return 42; // Hello
//}
//
//void A::bar() {
// int a = 42;
// int b = 42;
//}
//====================
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return EXTRACTED; // Hello
//}
//
//void A::bar() {
// int a = EXTRACTED;
// int b = EXTRACTED;
//}
//refactoringScript.xml
//<?xml version="1.0" encoding="UTF-8"?>
//<session version="1.0">
//<refactoring comment="Create constant for 42" description="Extract Constant Refactoring"
//fileName="file:${projectPath}/A.cpp" flags="4"
//id="org.eclipse.cdt.ui.refactoring.extractconstant.ExtractConstantRefactoring" name="EXTRACTED"
//project="RegressionTestProject" selection="64,2" visibility="public"/>
//</session>
//
public void testHistoryExtractConstantInt() throws Exception {
assertRefactoringSuccess();
}
//A.h
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
//};
//
//#endif /*A_H_*/
//====================
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
//
//protected:
// static const int EXTRACTED = 42;
//};
//
//#endif /*A_H_*/
//A.cpp
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return 42;
//}
//====================
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return EXTRACTED;
//}
//refactoringScript.xml
//<?xml version="1.0" encoding="UTF-8"?>
//<session version="1.0">
//<refactoring comment="Create constant for 42" description="Extract Constant Refactoring"
//fileName="file:${projectPath}/A.cpp" flags="4"
//id="org.eclipse.cdt.ui.refactoring.extractconstant.ExtractConstantRefactoring" name="EXTRACTED"
//project="RegressionTestProject" selection="64,2" visibility="protected"/>
//</session>
public void testHistoryReplaceNumberProtected() throws Exception {
assertRefactoringSuccess();
}
//A.h
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
//};
//
//#endif /*A_H_*/
//====================
//#ifndef A_H_
//#define A_H_
//
//class A {
//public:
// A();
// virtual ~A();
// int foo();
//
//private:
// static const int EXTRACTED = 42;
//};
//
//#endif /*A_H_*/
//A.cpp
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return 42;
//}
//====================
//#include "A.h"
//
//A::A() {
//}
//
//A::~A() {
//}
//
//int A::foo() {
// return EXTRACTED;
//}
//refactoringScript.xml
//<?xml version="1.0" encoding="UTF-8"?>
//<session version="1.0">
//<refactoring comment="Create constant for 42" description="Extract Constant Refactoring"
//fileName="file:${projectPath}/A.cpp" flags="4"
//id="org.eclipse.cdt.ui.refactoring.extractconstant.ExtractConstantRefactoring" name="EXTRACTED"
//project="RegressionTestProject" selection="64,2" visibility="private"/>
//</session>
public void testHistoryReplaceNumberPrivate() throws Exception {
assertRefactoringSuccess();
}
//A.cpp
//void foo() {
// int a = -(/*$*/+(~(10))/*$$*/);
// int b = -(+(~(10)));
// int c = -(+(~(11)));
// int d = +(~(10));
// int e = (~10);
// int f = -(+(-(10)));
//}
//=
//A.cpp
//namespace {
//
//const int EXTRACTED = +(~(10));
//
//}
//
//void foo() {
// int a = -(EXTRACTED);
// int b = -(EXTRACTED);
// int c = -(+(~(11)));
// int d = EXTRACTED;
// int e = (~10);
// int f = -(+(-(10)));
//}
public void testExtractionOfUnaryExpressions() throws Exception {
assertRefactoringSuccess();
}
//A.cpp
//void foo() {
// int i = /*$*/2 * 21/*$$*/;
//}
//=
//namespace {
//
//const int EXTRACTED = 2 * 21;
//
//}
//
//void foo() {
// int i = EXTRACTED;
//}
public void testSingleBinaryExpression() throws Exception {
assertRefactoringSuccess();
}
//A.cpp
//void foo(int) {
// foo(/*$*/2 * 21/*$$*/);
//}
//=
//namespace {
//
//const int EXTRACTED = 2 * 21;
//
//}
//
//void foo(int) {
// foo(EXTRACTED);
//}
public void testBinaryExpressionInFunctionCall() throws Exception {
assertRefactoringSuccess();
}
//A.cpp
//void foo(int, int) {
// foo(/*$*/2, 21/*$$*/);
//}
public void testExtractTwoIndependentLiterals() throws Exception {
assertRefactoringFailure();
}
//A.cpp
//void foo(int, int) {
// /*$*/foo(2, 21)/*$$*/;
//}
public void testExtractFunctionCall() throws Exception {
assertRefactoringFailure();
}
//A.cpp
//void foo() {
// int i = 42;
//}
public void testNoSelection() throws Exception {
assertRefactoringFailure();
}
//A.cpp
//void foo() {
// int i = 15;
// int j = /*$*/i/*$$*/;
//}
public void testExtractIdentifier() throws Exception {
assertRefactoringFailure();
}
//A.cpp
//void foo() {
// int i = 4/*$*//*$$*/2;
//}
//=
//namespace {
//
//const int EXTRACTED = 42;
//
//}
//
//void foo() {
// int i = EXTRACTED;
//}
public void testCarretInLiteral() throws Exception {
assertRefactoringSuccess();
}
//A.cpp
//void foo() {
// int i = 42/*$*//*$$*/;
//}
//=
//namespace {
//
//const int EXTRACTED = 42;
//
//}
//
//void foo() {
// int i = EXTRACTED;
//}
public void testCarretAtLiteral() throws Exception {
assertRefactoringSuccess();
}
//A.cpp
//int i = /*$*/42/*$$*/;
public void testDefaultNameForIntegerLiteral() throws Exception {
runUpToInitialConditions();
ExtractConstantInfo refactoringInfo = refactoring.getRefactoringInfo();
assertEquals("_42", refactoringInfo.getName());
}
// A.cpp
// namespace NS_1 {
// int i_in_NS1, j_in_NS1;
// struct S_in_NS1;
// }
// namespace NS_2 {
// int i_in_NS2;
// struct S_in_NS2;
// }
// using NS_1::j_in_NS1;
// using namespace NS_2;
// int global_variable;
// void free_function();
// struct S {
// void function(int parameter) {
// int local_before;
// int local_at = /*$*/42/*$$*/;
// {
// int nested;
// }
// int local_after;
// }
// int member_variable;
// void member_function();
// };
public void testOccupiedAndFreeNamesInContext() throws Exception {
runUpToInitialConditions();
ExtractConstantInfo refactoringInfo = refactoring.getRefactoringInfo();
String[] expectedOccupiedNames = { "free_function", "function",
"global_variable", "i_in_NS2", "j_in_NS1", "local_after",
"local_at", "local_before", "member_function",
"member_variable", "parameter", "NS_1", "NS_2", "S",
"S_in_NS2" };
String[] expectedFreeNames = { "_42", "i_in_NS1", "nested", "S_in_NS1" };
String[] allNames = combine(expectedOccupiedNames, expectedFreeNames);
String[] usedNames = Arrays.stream(allNames)
.filter(refactoringInfo::isNameUsed)
.toArray(String[]::new);
String[] freeNames = Arrays.stream(allNames)
.filter(not(refactoringInfo::isNameUsed))
.toArray(String[]::new);
assertEquals(Arrays.toString(expectedOccupiedNames), Arrays.toString(usedNames));
assertEquals(Arrays.toString(expectedFreeNames), Arrays.toString(freeNames));
}
private <T> Predicate<? super T> not(Predicate<? super T> predicate) {
return predicate.negate()::test;
}
private String[] combine(String[] array1, String[] array2) {
String[] result = new String[array1.length + array2.length];
System.arraycopy(array1, 0, result, 0, array1.length);
System.arraycopy(array2, 0, result, array1.length, array2.length);
return result;
}
private void runUpToInitialConditions() throws CoreException {
createRefactoring();
refactoring.setContext(new CRefactoringContext(refactoring));
refactoring.checkInitialConditions(npm());
}
}