11#include "gmock/gmock.h"
12#include "gtest/gtest.h"
18using ::testing::UnorderedElementsAre;
22TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
23 FileName =
"Test.cpp";
26 [[void [[f^o^o]]() [[{
61 [[void [[Bar::[[b^a^z]]]]() [[{
65 FileName = "Test.hpp";
71 [[vo^id ]]foo[[()]] {[[
78 [[void [[f^o^o]]() [[{
88 [[void [[Bar::[[b^a^z]]]]() [[{
95 [[void [[f^o^o^]]() [[{ return; }]]]]
99 [[void [[f^o^o]]() [[{
107 F^oo(const Foo&) = delete;
113 template <typename> struct Foo { void fo^o(){} };
119 template <typename T> void fo^o() {}
120 template <> void fo^o<int>() {}
126 struct { void b^ar() {} } Bar;
135 struct Bar { void b^ar() {} };
150TEST_F(DefineOutlineTest, FailsWithoutSource) {
151 FileName = "Test.hpp";
152 llvm::StringRef Test =
"void fo^o() { return; }";
153 llvm::StringRef Expected =
154 "fail: Couldn't find a suitable implementation file.";
155 EXPECT_EQ(apply(Test), Expected);
158TEST_F(DefineOutlineTest, ApplyTest) {
159 ExtraFiles[
"Test.cpp"] =
"";
160 FileName =
"Test.hpp";
163 llvm::StringRef Test;
164 llvm::StringRef ExpectedHeader;
165 llvm::StringRef ExpectedSource;
169 "void fo^o() { return; }",
171 "void foo() { return; }",
175 "inline void fo^o() { return; }",
177 " void foo() { return; }",
181 "void fo^o(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) {}",
182 "void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;",
183 "void foo(int x, int y , int , int (*foo)(int) ) {}",
186 "struct Bar{Bar();}; void fo^o(Bar x = {}) {}",
187 "struct Bar{Bar();}; void foo(Bar x = {}) ;",
188 "void foo(Bar x ) {}",
193 class Foo {public: Foo(); Foo(int);};
196 Bar(int x) : f1(x) {}
201 class Foo {public: Foo(); Foo(int);};
204 Bar(int x) : f1(x) {}
213 class Foo {public: Foo(); Foo(int);};
216 B^ar(int x) : f1(x), f2(3) {}
221 class Foo {public: Foo(); Foo(int);};
228 "Bar::Bar(int x) : f1(x), f2(3) {}\n",
233 template <typename T> class Foo {
234 F^oo(T z) __attribute__((weak)) : bar(2){}
238 template <typename T> class Foo {
239 Foo(T z) __attribute__((weak)) ;
241 };template <typename T>
242inline Foo<T>::Foo(T z) __attribute__((weak)) : bar(2){}
249 virtual void f^oo() {}
255 " void A::foo() {}\n",
260 virtual virtual void virtual f^oo() {}
264 virtual virtual void virtual foo() ;
266 " void A::foo() {}\n",
271 virtual void foo() = 0;
274 void fo^o() override {}
278 virtual void foo() = 0;
281 void foo() override ;
283 "void B::foo() {}\n",
288 virtual void foo() = 0;
295 virtual void foo() = 0;
300 "void B::foo() {}\n",
305 virtual void foo() = 0;
308 void fo^o() final override {}
312 virtual void foo() = 0;
315 void foo() final override ;
317 "void B::foo() {}\n",
322 static void fo^o() {}
328 " void A::foo() {}\n",
333 static static void fo^o() {}
337 static static void foo() ;
339 " void A::foo() {}\n",
344 explicit Fo^o(int) {}
350 " Foo::Foo(int) {}\n",
355 explicit explicit Fo^o(int) {}
359 explicit explicit Foo(int) ;
361 " Foo::Foo(int) {}\n",
366 inline void f^oo(int) {}
372 " void A::foo(int) {}\n",
377 template <typename T, typename ...U> struct O1 {
378 template <class V, int A> struct O2 {
381 E f^oo(T, U..., V, E) { return E1; }
386 template <typename T, typename ...U> struct O1 {
387 template <class V, int A> struct O2 {
390 E foo(T, U..., V, E) ;
393 };template <typename T, typename ...U>
394template <class V, int A>
395inline typename O1<T, U...>::template O2<V, A>::E O1<T, U...>::template O2<V, A>::I::foo(T, U..., V, E) { return E1; }
400 "class A { ~A^(){} };",
401 "class A { ~A(); };",
409 template <typename T, typename, bool B = true>
410 T ^bar() { return {}; }
414 template <typename T, typename, bool B = true>
416 };template <typename T, typename, bool B>
417inline T Foo::bar() { return {}; }
424 template <typename T> struct Foo {
425 template <typename U, bool> T ^bar(const T& t, const U& u) { return {}; }
428 template <typename T> struct Foo {
429 template <typename U, bool> T bar(const T& t, const U& u) ;
430 };template <typename T>
431template <typename U, bool>
432inline T Foo<T>::bar(const T& t, const U& u) { return {}; }
436 for (
const auto &Case : Cases) {
437 SCOPED_TRACE(Case.Test);
438 llvm::StringMap<std::string> EditedFiles;
439 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
440 if (Case.ExpectedSource.empty()) {
441 EXPECT_TRUE(EditedFiles.empty());
443 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
444 testPath(
"Test.cpp"), Case.ExpectedSource)));
449TEST_F(DefineOutlineTest, InCppFile) {
450 FileName =
"Test.cpp";
453 llvm::StringRef Test;
454 llvm::StringRef ExpectedSource;
460 struct Foo { void ba^r() {} };
461 struct Bar { void foo(); };
469 struct Foo { void bar() ; };void Foo::bar() {}
470 struct Bar { void foo(); };
477 for (
const auto &Case : Cases) {
478 SCOPED_TRACE(Case.Test);
479 EXPECT_EQ(apply(Case.Test,
nullptr), Case.ExpectedSource);
483TEST_F(DefineOutlineTest, HandleMacros) {
484 llvm::StringMap<std::string> EditedFiles;
485 ExtraFiles[
"Test.cpp"] =
"";
486 FileName =
"Test.hpp";
487 ExtraArgs.push_back(
"-DVIRTUAL=virtual");
488 ExtraArgs.push_back(
"-DOVER=override");
491 llvm::StringRef Test;
492 llvm::StringRef ExpectedHeader;
493 llvm::StringRef ExpectedSource;
496 #define BODY { return; }
497 void f^oo()BODY)cpp",
499 #define BODY { return; }
505 void f^oo(){BODY})cpp",
512 #define TARGET void foo()
513 [[TARGET]]{ return; })cpp",
515 #define TARGET void foo()
517 "TARGET{ return; }"},
521 void [[TARGET]](){ return; })cpp",
525 "void TARGET(){ return; }"},
526 {R
"cpp(#define VIRT virtual
530 R"cpp(#define VIRT virtual
534 " void A::foo() {}\n"},
537 VIRTUAL void f^oo() {}
543 " void A::foo() {}\n"},
546 virtual void foo() = 0;
553 virtual void foo() = 0;
558 "void B::foo() {}\n"},
559 {R
"cpp(#define STUPID_MACRO(X) virtual
561 STUPID_MACRO(sizeof sizeof int) void f^oo() {}
563 R"cpp(#define STUPID_MACRO(X) virtual
565 STUPID_MACRO(sizeof sizeof int) void foo() ;
567 " void A::foo() {}\n"},
568 {R
"cpp(#define STAT static
572 R"cpp(#define STAT static
576 " void A::foo() {}\n"},
577 {R
"cpp(#define STUPID_MACRO(X) static
579 STUPID_MACRO(sizeof sizeof int) void f^oo() {}
581 R"cpp(#define STUPID_MACRO(X) static
583 STUPID_MACRO(sizeof sizeof int) void foo() ;
585 " void A::foo() {}\n"},
587 for (
const auto &Case : Cases) {
588 SCOPED_TRACE(Case.Test);
589 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
590 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
591 testPath(
"Test.cpp"), Case.ExpectedSource)));
595TEST_F(DefineOutlineTest, QualifyReturnValue) {
596 FileName =
"Test.hpp";
597 ExtraFiles[
"Test.cpp"] =
"";
600 llvm::StringRef Test;
601 llvm::StringRef ExpectedHeader;
602 llvm::StringRef ExpectedSource;
605 namespace a { class Foo{}; }
607 Foo fo^o() { return {}; })cpp",
609 namespace a { class Foo{}; }
612 "a::Foo foo() { return {}; }"},
617 Bar fo^o() { return {}; }
627 "a::Foo::Bar a::Foo::foo() { return {}; }\n"},
630 Foo fo^o() { return {}; })cpp",
634 "Foo foo() { return {}; }"},
636 llvm::StringMap<std::string> EditedFiles;
637 for (
auto &Case : Cases) {
638 apply(Case.Test, &EditedFiles);
639 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
640 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
641 testPath(
"Test.cpp"), Case.ExpectedSource)));
645TEST_F(DefineOutlineTest, QualifyFunctionName) {
646 FileName =
"Test.hpp";
648 llvm::StringRef TestHeader;
649 llvm::StringRef TestSource;
650 llvm::StringRef ExpectedHeader;
651 llvm::StringRef ExpectedSource;
671 "void a::b::Foo::foo() {}\n",
674 "namespace a { namespace b { void f^oo() {} } }",
676 "namespace a { namespace b { void foo() ; } }",
677 "namespace a{void b::foo() {} }",
680 "namespace a { namespace b { void f^oo() {} } }",
681 "using namespace a;",
682 "namespace a { namespace b { void foo() ; } }",
685 "using namespace a;void a::b::foo() {} ",
688 "namespace a { class A { ~A^(){} }; }",
690 "namespace a { class A { ~A(); }; }",
694 "namespace a { class A { ~A^(){} }; }",
696 "namespace a { class A { ~A(); }; }",
697 "namespace a{A::~A(){} }",
700 llvm::StringMap<std::string> EditedFiles;
701 for (
auto &Case : Cases) {
702 ExtraFiles[
"Test.cpp"] = std::string(Case.TestSource);
703 EXPECT_EQ(apply(Case.TestHeader, &EditedFiles), Case.ExpectedHeader);
704 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
705 testPath(
"Test.cpp"), Case.ExpectedSource)))
710TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
711 FileName =
"Test.hpp";
712 ExtraFiles[
"Test.cpp"] =
"";
713 ExtraArgs.push_back(
"-DFINALOVER=final override");
715 std::pair<StringRef, StringRef> Cases[] = {
718 #define VIRT virtual void
722 "fail: define outline: couldn't remove `virtual` keyword."},
725 #define OVERFINAL final override
727 virtual void foo() {}
730 void fo^o() OVERFINAL {}
732 "fail: define outline: Can't move out of line as function has a "
733 "macro `override` specifier.\ndefine outline: Can't move out of line "
734 "as function has a macro `final` specifier."},
738 virtual void foo() {}
741 void fo^o() FINALOVER {}
743 "fail: define outline: Can't move out of line as function has a "
744 "macro `override` specifier.\ndefine outline: Can't move out of line "
745 "as function has a macro `final` specifier."},
747 for (
const auto &Case : Cases) {
748 EXPECT_EQ(apply(Case.first), Case.second);
757TEST_F(DefineOutlineWorkspaceTest, FindsCorrespondingSource) {
758 llvm::Annotations HeaderBefore(R
"cpp(
764 std::string SourceBefore(R"cpp(
768 std::string HeaderAfter = R"cpp(
774 std::string SourceAfter = R"cpp(
779 Workspace.addSource("a.hpp", HeaderBefore.code());
780 Workspace.addMainFile(
"a.cpp", SourceBefore);
781 auto Result = apply(
"a.hpp", {HeaderBefore.point(), HeaderBefore.point()});
783 AllOf(withStatus(
"success"),
785 FileWithContents(
testPath(
"a.hpp"), HeaderAfter),
786 FileWithContents(
testPath(
"a.cpp"), SourceAfter)))));
#define TWEAK_TEST(TweakID)
#define TWEAK_WORKSPACE_TEST(TweakID)
#define EXPECT_AVAILABLE(MarkedCode)
#define EXPECT_UNAVAILABLE(MarkedCode)
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
std::string testPath(PathRef File, llvm::sys::path::Style Style)
::testing::Matcher< TweakResult > editedFiles(EditedFilesMatcher M)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//