summaryrefslogtreecommitdiffstats
path: root/unittests
diff options
context:
space:
mode:
authorHaojian Wu <hokein@google.com>2017-10-17 14:14:41 +0000
committerHaojian Wu <hokein@google.com>2017-10-17 14:14:41 +0000
commit942e003931fb4d7107fbe5e439966e1452e9ed33 (patch)
tree253f51f24f773aee3e2a075f8503ba491fefc148 /unittests
parent19e976a47167c7239e742fc508d644b714f10016 (diff)
[clang-rename] Rename enum.
Summary: * Add unit tests for renaming enum. * Support unscoped enum constants in expressions. Reviewers: ioeric Reviewed By: ioeric Subscribers: klimek, mgorny, cfe-commits Differential Revision: https://reviews.llvm.org/D38989 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315999 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests')
-rw-r--r--unittests/Rename/CMakeLists.txt1
-rw-r--r--unittests/Rename/RenameEnumTest.cpp189
2 files changed, 190 insertions, 0 deletions
diff --git a/unittests/Rename/CMakeLists.txt b/unittests/Rename/CMakeLists.txt
index 763ba3b3b0..5a6875e0bc 100644
--- a/unittests/Rename/CMakeLists.txt
+++ b/unittests/Rename/CMakeLists.txt
@@ -7,6 +7,7 @@ include_directories(${CLANG_SOURCE_DIR})
add_clang_unittest(ClangRenameTests
RenameClassTest.cpp
+ RenameEnumTest.cpp
RenameFunctionTest.cpp
)
diff --git a/unittests/Rename/RenameEnumTest.cpp b/unittests/Rename/RenameEnumTest.cpp
new file mode 100644
index 0000000000..55dcd11ac4
--- /dev/null
+++ b/unittests/Rename/RenameEnumTest.cpp
@@ -0,0 +1,189 @@
+#include "ClangRenameTest.h"
+
+namespace clang {
+namespace clang_rename {
+namespace test {
+namespace {
+
+class RenameEnumTest : public ClangRenameTest {
+public:
+ RenameEnumTest() {
+ AppendToHeader(R"(
+ #define MACRO(x) x
+ namespace a {
+ enum A1 { Red };
+ enum class A2 { Blue };
+ struct C {
+ enum NestedEnum { White };
+ enum class NestedScopedEnum { Black };
+ };
+ namespace d {
+ enum A3 { Orange };
+ } // namespace d
+ enum A4 { Pink };
+ } // namespace a
+ enum A5 { Green };)");
+ }
+};
+
+INSTANTIATE_TEST_CASE_P(
+ RenameEnumTests, RenameEnumTest,
+ testing::ValuesIn(std::vector<Case>({
+ {"void f(a::A2 arg) { a::A2 t = a::A2::Blue; }",
+ "void f(b::B2 arg) { b::B2 t = b::B2::Blue; }", "a::A2", "b::B2"},
+ {"void f() { a::A1* t1; }", "void f() { b::B1* t1; }", "a::A1",
+ "b::B1"},
+ {"void f() { a::A2* t1; }", "void f() { b::B2* t1; }", "a::A2",
+ "b::B2"},
+ {"void f() { enum a::A2 t = a::A2::Blue; }",
+ "void f() { enum b::B2 t = b::B2::Blue; }", "a::A2", "b::B2"},
+ {"void f() { enum a::A2 t = a::A2::Blue; }",
+ "void f() { enum b::B2 t = b::B2::Blue; }", "a::A2", "b::B2"},
+
+ {"void f() { a::A1 t = a::Red; }", "void f() { b::B1 t = b::B1::Red; }",
+ "a::A1", "b::B1"},
+ {"void f() { a::A1 t = a::A1::Red; }",
+ "void f() { b::B1 t = b::B1::Red; }", "a::A1", "b::B1"},
+ {"void f() { auto t = a::Red; }", "void f() { auto t = b::B1::Red; }",
+ "a::A1", "b::B1"},
+ {"namespace b { void f() { a::A1 t = a::Red; } }",
+ "namespace b { void f() { B1 t = B1::Red; } }", "a::A1", "b::B1"},
+ {"void f() { a::d::A3 t = a::d::Orange; }",
+ "void f() { a::b::B3 t = a::b::B3::Orange; }", "a::d::A3", "a::b::B3"},
+ {"namespace a { void f() { a::d::A3 t = a::d::Orange; } }",
+ "namespace a { void f() { b::B3 t = b::B3::Orange; } }", "a::d::A3",
+ "a::b::B3"},
+ {"void f() { A5 t = Green; }", "void f() { B5 t = Green; }", "A5",
+ "B5"},
+ // FIXME: the new namespace qualifier should be added to the unscoped
+ // enum constant.
+ {"namespace a { void f() { auto t = Green; } }",
+ "namespace a { void f() { auto t = Green; } }", "a::A1", "b::B1"},
+
+ // namespace qualifiers
+ {"namespace a { void f(A1 a1) {} }",
+ "namespace a { void f(b::B1 a1) {} }", "a::A1", "b::B1"},
+ {"namespace a { void f(A2 a2) {} }",
+ "namespace a { void f(b::B2 a2) {} }", "a::A2", "b::B2"},
+ {"namespace b { void f(a::A1 a1) {} }",
+ "namespace b { void f(B1 a1) {} }", "a::A1", "b::B1"},
+ {"namespace b { void f(a::A2 a2) {} }",
+ "namespace b { void f(B2 a2) {} }", "a::A2", "b::B2"},
+
+ // nested enums
+ {"void f() { a::C::NestedEnum t = a::C::White; }",
+ "void f() { a::C::NewNestedEnum t = a::C::NewNestedEnum::White; }",
+ "a::C::NestedEnum", "a::C::NewNestedEnum"},
+ {"void f() { a::C::NestedScopedEnum t = a::C::NestedScopedEnum::Black; "
+ "}",
+ "void f() { a::C::NewNestedScopedEnum t = "
+ "a::C::NewNestedScopedEnum::Black; }",
+ "a::C::NestedScopedEnum", "a::C::NewNestedScopedEnum"},
+
+ // macros
+ {"void f(MACRO(a::A1) a1) {}", "void f(MACRO(b::B1) a1) {}", "a::A1",
+ "b::B1"},
+ {"void f(MACRO(a::A2) a2) {}", "void f(MACRO(b::B2) a2) {}", "a::A2",
+ "b::B2"},
+ {"#define FOO(T, t) T t\nvoid f() { FOO(a::A1, a1); }",
+ "#define FOO(T, t) T t\nvoid f() { FOO(b::B1, a1); }", "a::A1",
+ "b::B1"},
+ {"#define FOO(T, t) T t\nvoid f() { FOO(a::A2, a2); }",
+ "#define FOO(T, t) T t\nvoid f() { FOO(b::B2, a2); }", "a::A2",
+ "b::B2"},
+ {"#define FOO(n) a::A1 n\nvoid f() { FOO(a1); FOO(a2); }",
+ "#define FOO(n) b::B1 n\nvoid f() { FOO(a1); FOO(a2); }", "a::A1",
+ "b::B1"},
+
+ // using and type alias
+ {"using a::A1; A1 gA;", "using b::B1; b::B1 gA;", "a::A1", "b::B1"},
+ {"using a::A2; A2 gA;", "using b::B2; b::B2 gA;", "a::A2", "b::B2"},
+ {"struct S { using T = a::A1; T a_; };",
+ "struct S { using T = b::B1; T a_; };", "a::A1", "b::B1"},
+ {"using T = a::A1; T gA;", "using T = b::B1; T gA;", "a::A1", "b::B1"},
+ {"using T = a::A2; T gA;", "using T = b::B2; T gA;", "a::A2", "b::B2"},
+ {"typedef a::A1 T; T gA;", "typedef b::B1 T; T gA;", "a::A1", "b::B1"},
+ {"typedef a::A2 T; T gA;", "typedef b::B2 T; T gA;", "a::A2", "b::B2"},
+ {"typedef MACRO(a::A1) T; T gA;", "typedef MACRO(b::B1) T; T gA;",
+ "a::A1", "b::B1"},
+
+ // templates
+ {"template<typename T> struct Foo { T t; }; void f() { Foo<a::A1> "
+ "foo1; }",
+ "template<typename T> struct Foo { T t; }; void f() { Foo<b::B1> "
+ "foo1; }",
+ "a::A1", "b::B1"},
+ {"template<typename T> struct Foo { T t; }; void f() { Foo<a::A2> "
+ "foo2; }",
+ "template<typename T> struct Foo { T t; }; void f() { Foo<b::B2> "
+ "foo2; }",
+ "a::A2", "b::B2"},
+ {"template<typename T> struct Foo { a::A1 a1; };",
+ "template<typename T> struct Foo { b::B1 a1; };", "a::A1", "b::B1"},
+ {"template<typename T> struct Foo { a::A2 a2; };",
+ "template<typename T> struct Foo { b::B2 a2; };", "a::A2", "b::B2"},
+ {"template<typename T> int f() { return 1; } template<> int f<a::A1>() "
+ "{ return 2; } int g() { return f<a::A1>(); }",
+ "template<typename T> int f() { return 1; } template<> int f<b::B1>() "
+ "{ return 2; } int g() { return f<b::B1>(); }",
+ "a::A1", "b::B1"},
+ {"template<typename T> int f() { return 1; } template<> int f<a::A2>() "
+ "{ return 2; } int g() { return f<a::A2>(); }",
+ "template<typename T> int f() { return 1; } template<> int f<b::B2>() "
+ "{ return 2; } int g() { return f<b::B2>(); }",
+ "a::A2", "b::B2"},
+ {"struct Foo { template <typename T> T foo(); }; void g() { Foo f; "
+ "f.foo<a::A1>(); }",
+ "struct Foo { template <typename T> T foo(); }; void g() { Foo f; "
+ "f.foo<b::B1>(); }",
+ "a::A1", "b::B1"},
+ {"struct Foo { template <typename T> T foo(); }; void g() { Foo f; "
+ "f.foo<a::A2>(); }",
+ "struct Foo { template <typename T> T foo(); }; void g() { Foo f; "
+ "f.foo<b::B2>(); }",
+ "a::A2", "b::B2"},
+ })), );
+
+TEST_P(RenameEnumTest, RenameEnums) {
+ auto Param = GetParam();
+ assert(!Param.OldName.empty());
+ assert(!Param.NewName.empty());
+ std::string Actual =
+ runClangRenameOnCode(Param.Before, Param.OldName, Param.NewName);
+ CompareSnippets(Param.After, Actual);
+}
+
+TEST_F(RenameEnumTest, RenameEnumDecl) {
+ std::string Before = R"(
+ namespace ns {
+ enum Old1 { Blue };
+ }
+ )";
+ std::string Expected = R"(
+ namespace ns {
+ enum New1 { Blue };
+ }
+ )";
+ std::string After = runClangRenameOnCode(Before, "ns::Old1", "ns::New1");
+ CompareSnippets(Expected, After);
+}
+
+TEST_F(RenameEnumTest, RenameScopedEnumDecl) {
+ std::string Before = R"(
+ namespace ns {
+ enum class Old1 { Blue };
+ }
+ )";
+ std::string Expected = R"(
+ namespace ns {
+ enum class New1 { Blue };
+ }
+ )";
+ std::string After = runClangRenameOnCode(Before, "ns::Old1", "ns::New1");
+ CompareSnippets(Expected, After);
+}
+
+} // anonymous namespace
+} // namespace test
+} // namespace clang_rename
+} // namesdpace clang