11#include "gmock/gmock.h"
12#include "gtest/gtest.h"
20TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
24 [[void [[f^o^o]]() [[{
59 [[void [[Bar::[[b^a^z]]]]() [[{
69 [[vo^id ]]foo[[()]] {[[
76 [[void [[f^o^o]]() [[{
86 [[void [[Bar::[[b^a^z]]]]() [[{
93 [[void [[f^o^o^]]() [[{ return; }]]]]
97 [[void [[f^o^o]]() [[{
105 F^oo(const Foo&) = delete;
111 template <typename> struct Foo { void fo^o(){} };
117 template <typename> void fo^o() {};
118 template <> void fo^o<int>() {};
124 struct { void b^ar() {} } Bar;
133 struct Bar { void b^ar() {} };
148TEST_F(DefineOutlineTest, FailsWithoutSource) {
150 llvm::StringRef Test =
"void fo^o() { return; }";
152 "fail: Couldn't find a suitable implementation file.";
156TEST_F(DefineOutlineTest, ApplyTest) {
157 llvm::StringMap<std::string> EditedFiles;
158 ExtraFiles[
"Test.cpp"] =
"";
162 llvm::StringRef Test;
163 llvm::StringRef ExpectedHeader;
164 llvm::StringRef ExpectedSource;
168 "void fo^o() { return; }",
170 "void foo() { return; }",
174 "inline void fo^o() { return; }",
176 " void foo() { return; }",
180 "void fo^o(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) {}",
181 "void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;",
182 "void foo(int x, int y , int , int (*foo)(int) ) {}",
185 "struct Bar{Bar();}; void fo^o(Bar x = {}) {}",
186 "struct Bar{Bar();}; void foo(Bar x = {}) ;",
187 "void foo(Bar x ) {}",
192 class Foo {public: Foo(); Foo(int);};
195 Bar(int x) : f1(x) {}
200 class Foo {public: Foo(); Foo(int);};
203 Bar(int x) : f1(x) {}
212 class Foo {public: Foo(); Foo(int);};
215 B^ar(int x) : f1(x), f2(3) {}
220 class Foo {public: Foo(); Foo(int);};
227 "Bar::Bar(int x) : f1(x), f2(3) {}\n",
233 F^oo(int z) __attribute__((weak)) : bar(2){}
238 Foo(int z) __attribute__((weak)) ;
241 "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
247 virtual void f^oo() {}
253 " void A::foo() {}\n",
258 virtual virtual void virtual f^oo() {}
262 virtual virtual void virtual foo() ;
264 " void A::foo() {}\n",
269 virtual void foo() = 0;
272 void fo^o() override {}
276 virtual void foo() = 0;
279 void foo() override ;
281 "void B::foo() {}\n",
286 virtual void foo() = 0;
293 virtual void foo() = 0;
298 "void B::foo() {}\n",
303 virtual void foo() = 0;
306 void fo^o() final override {}
310 virtual void foo() = 0;
313 void foo() final override ;
315 "void B::foo() {}\n",
320 static void fo^o() {}
326 " void A::foo() {}\n",
331 static static void fo^o() {}
335 static static void foo() ;
337 " void A::foo() {}\n",
342 explicit Fo^o(int) {}
348 " Foo::Foo(int) {}\n",
353 explicit explicit Fo^o(int) {}
357 explicit explicit Foo(int) ;
359 " Foo::Foo(int) {}\n",
364 inline void f^oo(int) {}
370 " void A::foo(int) {}\n",
374 "class A { ~A^(){} };",
375 "class A { ~A(); };",
379 for (
const auto &Case : Cases) {
380 SCOPED_TRACE(Case.Test);
381 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
382 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
383 testPath(
"Test.cpp"), Case.ExpectedSource)));
387TEST_F(DefineOutlineTest, InCppFile) {
391 llvm::StringRef Test;
392 llvm::StringRef ExpectedSource;
398 struct Foo { void ba^r() {} };
399 struct Bar { void foo(); };
407 struct Foo { void bar() ; };void Foo::bar() {}
408 struct Bar { void foo(); };
415 for (
const auto &Case : Cases) {
416 SCOPED_TRACE(Case.Test);
417 EXPECT_EQ(apply(Case.Test,
nullptr), Case.ExpectedSource);
421TEST_F(DefineOutlineTest, HandleMacros) {
422 llvm::StringMap<std::string> EditedFiles;
423 ExtraFiles[
"Test.cpp"] =
"";
425 ExtraArgs.push_back(
"-DVIRTUAL=virtual");
426 ExtraArgs.push_back(
"-DOVER=override");
429 llvm::StringRef Test;
430 llvm::StringRef ExpectedHeader;
431 llvm::StringRef ExpectedSource;
434 #define BODY { return; }
435 void f^oo()BODY)cpp",
437 #define BODY { return; }
443 void f^oo(){BODY})cpp",
450 #define TARGET void foo()
451 [[TARGET]]{ return; })cpp",
453 #define TARGET void foo()
455 "TARGET{ return; }"},
459 void [[TARGET]](){ return; })cpp",
463 "void TARGET(){ return; }"},
464 {R
"cpp(#define VIRT virtual
468 R"cpp(#define VIRT virtual
472 " void A::foo() {}\n"},
475 VIRTUAL void f^oo() {}
481 " void A::foo() {}\n"},
484 virtual void foo() = 0;
491 virtual void foo() = 0;
496 "void B::foo() {}\n"},
497 {R
"cpp(#define STUPID_MACRO(X) virtual
499 STUPID_MACRO(sizeof sizeof int) void f^oo() {}
501 R"cpp(#define STUPID_MACRO(X) virtual
503 STUPID_MACRO(sizeof sizeof int) void foo() ;
505 " void A::foo() {}\n"},
506 {R
"cpp(#define STAT static
510 R"cpp(#define STAT static
514 " void A::foo() {}\n"},
515 {R
"cpp(#define STUPID_MACRO(X) static
517 STUPID_MACRO(sizeof sizeof int) void f^oo() {}
519 R"cpp(#define STUPID_MACRO(X) static
521 STUPID_MACRO(sizeof sizeof int) void foo() ;
523 " void A::foo() {}\n"},
525 for (
const auto &Case : Cases) {
526 SCOPED_TRACE(Case.Test);
527 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
528 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
529 testPath(
"Test.cpp"), Case.ExpectedSource)));
533TEST_F(DefineOutlineTest, QualifyReturnValue) {
535 ExtraFiles[
"Test.cpp"] =
"";
538 llvm::StringRef Test;
539 llvm::StringRef ExpectedHeader;
540 llvm::StringRef ExpectedSource;
543 namespace a { class Foo{}; }
545 Foo fo^o() { return {}; })cpp",
547 namespace a { class Foo{}; }
550 "a::Foo foo() { return {}; }"},
555 Bar fo^o() { return {}; }
565 "a::Foo::Bar a::Foo::foo() { return {}; }\n"},
568 Foo fo^o() { return {}; })cpp",
572 "Foo foo() { return {}; }"},
574 llvm::StringMap<std::string> EditedFiles;
575 for (
auto &Case : Cases) {
576 apply(Case.Test, &EditedFiles);
577 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
578 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
579 testPath(
"Test.cpp"), Case.ExpectedSource)));
583TEST_F(DefineOutlineTest, QualifyFunctionName) {
586 llvm::StringRef TestHeader;
587 llvm::StringRef TestSource;
588 llvm::StringRef ExpectedHeader;
589 llvm::StringRef ExpectedSource;
609 "void a::b::Foo::foo() {}\n",
612 "namespace a { namespace b { void f^oo() {} } }",
614 "namespace a { namespace b { void foo() ; } }",
615 "namespace a{void b::foo() {} }",
618 "namespace a { namespace b { void f^oo() {} } }",
619 "using namespace a;",
620 "namespace a { namespace b { void foo() ; } }",
623 "using namespace a;void a::b::foo() {} ",
626 "namespace a { class A { ~A^(){} }; }",
628 "namespace a { class A { ~A(); }; }",
632 "namespace a { class A { ~A^(){} }; }",
634 "namespace a { class A { ~A(); }; }",
635 "namespace a{A::~A(){} }",
638 llvm::StringMap<std::string> EditedFiles;
639 for (
auto &Case : Cases) {
640 ExtraFiles[
"Test.cpp"] = std::string(Case.TestSource);
641 EXPECT_EQ(apply(Case.TestHeader, &EditedFiles), Case.ExpectedHeader);
642 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
643 testPath(
"Test.cpp"), Case.ExpectedSource)))
648TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
650 ExtraFiles[
"Test.cpp"] =
"";
651 ExtraArgs.push_back(
"-DFINALOVER=final override");
653 std::pair<StringRef, StringRef> Cases[] = {
656 #define VIRT virtual void
660 "fail: define outline: couldn't remove `virtual` keyword."},
663 #define OVERFINAL final override
665 virtual void foo() {}
668 void fo^o() OVERFINAL {}
670 "fail: define outline: Can't move out of line as function has a "
671 "macro `override` specifier.\ndefine outline: Can't move out of line "
672 "as function has a macro `final` specifier."},
676 virtual void foo() {}
679 void fo^o() FINALOVER {}
681 "fail: define outline: Can't move out of line as function has a "
682 "macro `override` specifier.\ndefine outline: Can't move out of line "
683 "as function has a macro `final` specifier."},
685 for (
const auto &Case : Cases) {
686 EXPECT_EQ(apply(Case.first), Case.second);
std::vector< const char * > Expected
#define TWEAK_TEST(TweakID)
#define EXPECT_AVAILABLE(MarkedCode)
#define EXPECT_UNAVAILABLE(MarkedCode)
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
std::string testPath(PathRef File, llvm::sys::path::Style Style)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//