[PATCH] D53081: [clang-doc] Add unit tests for serialization
This revision was automatically updated to reflect the committed changes. Closed by commit rCTE344650: [clang-doc] Add unit tests for serialization (authored by juliehockett, committed by ). Changed prior to commit: https://reviews.llvm.org/D53081?vs=169754=169907#toc Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D53081 Files: unittests/CMakeLists.txt unittests/clang-doc/CMakeLists.txt unittests/clang-doc/ClangDocTest.cpp unittests/clang-doc/ClangDocTest.h unittests/clang-doc/SerializeTest.cpp Index: unittests/clang-doc/ClangDocTest.cpp === --- unittests/clang-doc/ClangDocTest.cpp +++ unittests/clang-doc/ClangDocTest.cpp @@ -0,0 +1,182 @@ +//===-- clang-doc/ClangDocTest.cpp ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "Representation.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "gtest/gtest.h" + +namespace clang { +namespace doc { + +NamespaceInfo *InfoAsNamespace(Info *I) { + assert(I->IT == InfoType::IT_namespace); + return static_cast(I); +} + +RecordInfo *InfoAsRecord(Info *I) { + assert(I->IT == InfoType::IT_record); + return static_cast(I); +} + +FunctionInfo *InfoAsFunction(Info *I) { + assert(I->IT == InfoType::IT_function); + return static_cast(I); +} + +EnumInfo *InfoAsEnum(Info *I) { + assert(I->IT == InfoType::IT_enum); + return static_cast(I); +} + +void CheckCommentInfo(CommentInfo , CommentInfo ) { + EXPECT_EQ(Expected.Kind, Actual.Kind); + EXPECT_EQ(Expected.Text, Actual.Text); + EXPECT_EQ(Expected.Name, Actual.Name); + EXPECT_EQ(Expected.Direction, Actual.Direction); + EXPECT_EQ(Expected.ParamName, Actual.ParamName); + EXPECT_EQ(Expected.CloseName, Actual.CloseName); + EXPECT_EQ(Expected.SelfClosing, Actual.SelfClosing); + EXPECT_EQ(Expected.Explicit, Actual.Explicit); + + ASSERT_EQ(Expected.AttrKeys.size(), Actual.AttrKeys.size()); + for (size_t Idx = 0; Idx < Actual.AttrKeys.size(); ++Idx) +EXPECT_EQ(Expected.AttrKeys[Idx], Actual.AttrKeys[Idx]); + + ASSERT_EQ(Expected.AttrValues.size(), Actual.AttrValues.size()); + for (size_t Idx = 0; Idx < Actual.AttrValues.size(); ++Idx) +EXPECT_EQ(Expected.AttrValues[Idx], Actual.AttrValues[Idx]); + + ASSERT_EQ(Expected.Args.size(), Actual.Args.size()); + for (size_t Idx = 0; Idx < Actual.Args.size(); ++Idx) +EXPECT_EQ(Expected.Args[Idx], Actual.Args[Idx]); + + ASSERT_EQ(Expected.Children.size(), Actual.Children.size()); + for (size_t Idx = 0; Idx < Actual.Children.size(); ++Idx) +CheckCommentInfo(*Expected.Children[Idx], *Actual.Children[Idx]); +} + +void CheckReference(Reference , Reference ) { + EXPECT_EQ(Expected.Name, Actual.Name); + EXPECT_EQ(Expected.RefType, Actual.RefType); +} + +void CheckTypeInfo(TypeInfo *Expected, TypeInfo *Actual) { + CheckReference(Expected->Type, Actual->Type); +} + +void CheckFieldTypeInfo(FieldTypeInfo *Expected, FieldTypeInfo *Actual) { + CheckTypeInfo(Expected, Actual); + EXPECT_EQ(Expected->Name, Actual->Name); +} + +void CheckMemberTypeInfo(MemberTypeInfo *Expected, MemberTypeInfo *Actual) { + CheckFieldTypeInfo(Expected, Actual); + EXPECT_EQ(Expected->Access, Actual->Access); +} + +void CheckBaseInfo(Info *Expected, Info *Actual) { + EXPECT_EQ(size_t(20), Actual->USR.size()); + EXPECT_EQ(Expected->Name, Actual->Name); + ASSERT_EQ(Expected->Namespace.size(), Actual->Namespace.size()); + for (size_t Idx = 0; Idx < Actual->Namespace.size(); ++Idx) +CheckReference(Expected->Namespace[Idx], Actual->Namespace[Idx]); + ASSERT_EQ(Expected->Description.size(), Actual->Description.size()); + for (size_t Idx = 0; Idx < Actual->Description.size(); ++Idx) +CheckCommentInfo(Expected->Description[Idx], Actual->Description[Idx]); +} + +void CheckSymbolInfo(SymbolInfo *Expected, SymbolInfo *Actual) { + CheckBaseInfo(Expected, Actual); + EXPECT_EQ(Expected->DefLoc.hasValue(), Actual->DefLoc.hasValue()); + if (Expected->DefLoc.hasValue() && Actual->DefLoc.hasValue()) { +EXPECT_EQ(Expected->DefLoc->LineNumber, Actual->DefLoc->LineNumber); +EXPECT_EQ(Expected->DefLoc->Filename, Actual->DefLoc->Filename); + } + ASSERT_EQ(Expected->Loc.size(), Actual->Loc.size()); + for (size_t Idx = 0; Idx < Actual->Loc.size(); ++Idx) +EXPECT_EQ(Expected->Loc[Idx], Actual->Loc[Idx]); +} + +void CheckFunctionInfo(FunctionInfo *Expected, FunctionInfo *Actual) { + CheckSymbolInfo(Expected, Actual); + + EXPECT_EQ(Expected->IsMethod, Actual->IsMethod); + CheckReference(Expected->Parent, Actual->Parent); + CheckTypeInfo(>ReturnType, >ReturnType); + + ASSERT_EQ(Expected->Params.size(), Actual->Params.size()); + for (size_t Idx = 0; Idx < Actual->Params.size(); ++Idx) +
[PATCH] D53081: [clang-doc] Add unit tests for serialization
jakehehrlich accepted this revision. jakehehrlich added a comment. This revision is now accepted and ready to land. LGTM, I'd file a bug about SmallString not taking const char* in its constructor and I'd also put a TODO somewhere to fix that once that's resolved. https://reviews.llvm.org/D53081 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D53081: [clang-doc] Add unit tests for serialization
juliehockett updated this revision to Diff 169754. juliehockett marked an inline comment as done. https://reviews.llvm.org/D53081 Files: clang-tools-extra/unittests/CMakeLists.txt clang-tools-extra/unittests/clang-doc/CMakeLists.txt clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp clang-tools-extra/unittests/clang-doc/ClangDocTest.h clang-tools-extra/unittests/clang-doc/SerializeTest.cpp Index: clang-tools-extra/unittests/clang-doc/SerializeTest.cpp === --- /dev/null +++ clang-tools-extra/unittests/clang-doc/SerializeTest.cpp @@ -0,0 +1,346 @@ +//===-- clang-doc/SerializeTest.cpp ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "Serialize.h" +#include "ClangDocTest.h" +#include "Representation.h" +#include "clang/AST/Comment.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "gtest/gtest.h" + +namespace clang { +namespace doc { + +class ClangDocSerializeTestVisitor +: public RecursiveASTVisitor { + + EmittedInfoList + bool Public; + + comments::FullComment *getComment(const NamedDecl *D) const { +if (RawComment *Comment = +D->getASTContext().getRawCommentForDeclNoCache(D)) { + Comment->setAttached(); + return Comment->parse(D->getASTContext(), nullptr, D); +} +return nullptr; + } + +public: + ClangDocSerializeTestVisitor(EmittedInfoList , bool Public) + : EmittedInfos(EmittedInfos), Public(Public) {} + + bool VisitNamespaceDecl(const NamespaceDecl *D) { +auto I = serialize::emitInfo(D, getComment(D), /*Line=*/0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } + + bool VisitFunctionDecl(const FunctionDecl *D) { +// Don't visit CXXMethodDecls twice +if (dyn_cast(D)) + return true; +auto I = serialize::emitInfo(D, getComment(D), /*Line=*/0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } + + bool VisitCXXMethodDecl(const CXXMethodDecl *D) { +auto I = serialize::emitInfo(D, getComment(D), /*Line=*/0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } + + bool VisitRecordDecl(const RecordDecl *D) { +auto I = serialize::emitInfo(D, getComment(D), /*Line=*/0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } + + bool VisitEnumDecl(const EnumDecl *D) { +auto I = serialize::emitInfo(D, getComment(D), /*Line=*/0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } +}; + +void ExtractInfosFromCode(StringRef Code, size_t NumExpectedInfos, bool Public, + EmittedInfoList ) { + auto ASTUnit = clang::tooling::buildASTFromCode(Code); + auto TU = ASTUnit->getASTContext().getTranslationUnitDecl(); + ClangDocSerializeTestVisitor Visitor(EmittedInfos, Public); + Visitor.TraverseTranslationUnitDecl(TU); + ASSERT_EQ(NumExpectedInfos, EmittedInfos.size()); +} + +void ExtractInfosFromCodeWithArgs(StringRef Code, size_t NumExpectedInfos, + bool Public, EmittedInfoList , + std::vector ) { + auto ASTUnit = clang::tooling::buildASTFromCodeWithArgs(Code, Args); + auto TU = ASTUnit->getASTContext().getTranslationUnitDecl(); + ClangDocSerializeTestVisitor Visitor(EmittedInfos, Public); + Visitor.TraverseTranslationUnitDecl(TU); + ASSERT_EQ(NumExpectedInfos, EmittedInfos.size()); +} + +// Test serialization of namespace declarations. +TEST(SerializeTest, emitNamespaceInfo) { + EmittedInfoList Infos; + ExtractInfosFromCode("namespace A { namespace B { void f() {} } }", 3, + /*Public=*/false, Infos); + + NamespaceInfo *A = InfoAsNamespace(Infos[0].get()); + NamespaceInfo ExpectedA(EmptySID, "A"); + CheckNamespaceInfo(, A); + + NamespaceInfo *B = InfoAsNamespace(Infos[1].get()); + NamespaceInfo ExpectedB(EmptySID, "B"); + ExpectedB.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace); + CheckNamespaceInfo(, B); + + NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[2].get()); + NamespaceInfo ExpectedBWithFunction(EmptySID); + FunctionInfo F; + F.Name = "f"; + F.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default); + F.DefLoc = Location(0, llvm::SmallString<16>("test.cpp")); + F.Namespace.emplace_back(EmptySID, "B", InfoType::IT_namespace); +
[PATCH] D53081: [clang-doc] Add unit tests for serialization
phosek added inline comments. Comment at: clang-tools-extra/unittests/clang-doc/SerializeTest.cpp:320 + ExtractInfosFromCodeWithArgs( + "export module M;\n" + "int moduleFunction(int x);\n" Can you use raw strings here (and elsewhere in this file) as well? https://reviews.llvm.org/D53081 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D53081: [clang-doc] Add unit tests for serialization
juliehockett updated this revision to Diff 169748. juliehockett marked 2 inline comments as done. https://reviews.llvm.org/D53081 Files: clang-tools-extra/unittests/CMakeLists.txt clang-tools-extra/unittests/clang-doc/CMakeLists.txt clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp clang-tools-extra/unittests/clang-doc/ClangDocTest.h clang-tools-extra/unittests/clang-doc/SerializeTest.cpp Index: clang-tools-extra/unittests/clang-doc/SerializeTest.cpp === --- /dev/null +++ clang-tools-extra/unittests/clang-doc/SerializeTest.cpp @@ -0,0 +1,349 @@ +//===-- clang-doc/SerializeTest.cpp ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "Serialize.h" +#include "ClangDocTest.h" +#include "Representation.h" +#include "clang/AST/Comment.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "gtest/gtest.h" + +namespace clang { +namespace doc { + +class ClangDocSerializeTestVisitor +: public RecursiveASTVisitor { + + EmittedInfoList + bool Public; + + comments::FullComment *getComment(const NamedDecl *D) const { +if (RawComment *Comment = +D->getASTContext().getRawCommentForDeclNoCache(D)) { + Comment->setAttached(); + return Comment->parse(D->getASTContext(), nullptr, D); +} +return nullptr; + } + +public: + ClangDocSerializeTestVisitor(EmittedInfoList , bool Public) + : EmittedInfos(EmittedInfos), Public(Public) {} + + bool VisitNamespaceDecl(const NamespaceDecl *D) { +auto I = serialize::emitInfo(D, getComment(D), /*Line=*/ 0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } + + bool VisitFunctionDecl(const FunctionDecl *D) { +// Don't visit CXXMethodDecls twice +if (dyn_cast(D)) + return true; +auto I = serialize::emitInfo(D, getComment(D), /*Line=*/ 0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } + + bool VisitCXXMethodDecl(const CXXMethodDecl *D) { +auto I = serialize::emitInfo(D, getComment(D), /*Line=*/ 0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } + + bool VisitRecordDecl(const RecordDecl *D) { +auto I = serialize::emitInfo(D, getComment(D), /*Line=*/ 0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } + + bool VisitEnumDecl(const EnumDecl *D) { +auto I = serialize::emitInfo(D, getComment(D), /*Line=*/ 0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } +}; + +void ExtractInfosFromCode(StringRef Code, size_t NumExpectedInfos, bool Public, + EmittedInfoList ) { + auto ASTUnit = clang::tooling::buildASTFromCode(Code); + auto TU = ASTUnit->getASTContext().getTranslationUnitDecl(); + ClangDocSerializeTestVisitor Visitor(EmittedInfos, Public); + Visitor.TraverseTranslationUnitDecl(TU); + ASSERT_EQ(NumExpectedInfos, EmittedInfos.size()); +} + +void ExtractInfosFromCodeWithArgs(StringRef Code, size_t NumExpectedInfos, + bool Public, EmittedInfoList , + std::vector ) { + auto ASTUnit = clang::tooling::buildASTFromCodeWithArgs(Code, Args); + auto TU = ASTUnit->getASTContext().getTranslationUnitDecl(); + ClangDocSerializeTestVisitor Visitor(EmittedInfos, Public); + Visitor.TraverseTranslationUnitDecl(TU); + ASSERT_EQ(NumExpectedInfos, EmittedInfos.size()); +} + +// Test serialization of namespace declarations. +TEST(SerializeTest, emitNamespaceInfo) { + EmittedInfoList Infos; + ExtractInfosFromCode("namespace A { namespace B { void f() {} } }", 3, + /*Public=*/false, Infos); + + NamespaceInfo *A = InfoAsNamespace(Infos[0].get()); + NamespaceInfo ExpectedA(EmptySID, "A"); + CheckNamespaceInfo(, A); + + NamespaceInfo *B = InfoAsNamespace(Infos[1].get()); + NamespaceInfo ExpectedB(EmptySID, "B"); + ExpectedB.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace); + CheckNamespaceInfo(, B); + + NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[2].get()); + NamespaceInfo ExpectedBWithFunction(EmptySID); + FunctionInfo F; + F.Name = "f"; + F.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default); + F.DefLoc = Location(0, llvm::SmallString<16>("test.cpp")); + F.Namespace.emplace_back(EmptySID, "B", InfoType::IT_namespace); +
[PATCH] D53081: [clang-doc] Add unit tests for serialization
phosek added inline comments. Comment at: clang-tools-extra/unittests/clang-doc/SerializeTest.cpp:27 +comments::FullComment * +getComment(const NamedDecl *D) const { + if (RawComment *Comment = D->getASTContext().getRawCommentForDeclNoCache(D)) { Nit: this function seems to be wrongly indented. Comment at: clang-tools-extra/unittests/clang-doc/SerializeTest.cpp:40 + bool VisitNamespaceDecl(const NamespaceDecl *D) { +auto I = serialize::emitInfo(D, getComment(D), /*Line*/ 0, + /*File=*/"test.cpp", Public); Nit: this should be `/*Line=*/` for consistency, the same below. https://reviews.llvm.org/D53081 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D53081: [clang-doc] Add unit tests for serialization
juliehockett created this revision. juliehockett added reviewers: leonardchan, jakehehrlich, lebedev.ri. juliehockett added a project: clang-tools-extra. Herald added subscribers: kadircet, arphaman, mgorny. This is part of a move to convert clang-doc's tests to a more maintainable unit test framework, with a smaller number of integration tests to maintain and more granular failure feedback. https://reviews.llvm.org/D53081 Files: clang-tools-extra/unittests/CMakeLists.txt clang-tools-extra/unittests/clang-doc/CMakeLists.txt clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp clang-tools-extra/unittests/clang-doc/ClangDocTest.h clang-tools-extra/unittests/clang-doc/SerializeTest.cpp Index: clang-tools-extra/unittests/clang-doc/SerializeTest.cpp === --- /dev/null +++ clang-tools-extra/unittests/clang-doc/SerializeTest.cpp @@ -0,0 +1,346 @@ +//===-- clang-doc/SerializeTest.cpp ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "Serialize.h" +#include "ClangDocTest.h" +#include "Representation.h" +#include "clang/AST/Comment.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "gtest/gtest.h" + +namespace clang { +namespace doc { + +class ClangDocSerializeTestVisitor +: public RecursiveASTVisitor { + + EmittedInfoList + bool Public; + +comments::FullComment * +getComment(const NamedDecl *D) const { + if (RawComment *Comment = D->getASTContext().getRawCommentForDeclNoCache(D)) { +Comment->setAttached(); +return Comment->parse(D->getASTContext(), nullptr, D); + } + return nullptr; +} + +public: + ClangDocSerializeTestVisitor(EmittedInfoList , bool Public) + : EmittedInfos(EmittedInfos), Public(Public) {} + + bool VisitNamespaceDecl(const NamespaceDecl *D) { +auto I = serialize::emitInfo(D, getComment(D), /*Line*/ 0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } + + bool VisitFunctionDecl(const FunctionDecl *D) { +// Don't visit CXXMethodDecls twice +if (dyn_cast(D)) + return true; +auto I = serialize::emitInfo(D, getComment(D), /*Line*/ 0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } + + bool VisitCXXMethodDecl(const CXXMethodDecl *D) { +auto I = serialize::emitInfo(D, getComment(D), /*Line*/ 0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } + + bool VisitRecordDecl(const RecordDecl *D) { +auto I = serialize::emitInfo(D, getComment(D), /*Line*/ 0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } + + bool VisitEnumDecl(const EnumDecl *D) { +auto I = serialize::emitInfo(D, getComment(D), /*Line*/ 0, + /*File=*/"test.cpp", Public); +if (I) + EmittedInfos.emplace_back(std::move(I)); +return true; + } +}; + +void ExtractInfosFromCode(StringRef Code, size_t NumExpectedInfos, bool Public, + EmittedInfoList ) { + auto ASTUnit = clang::tooling::buildASTFromCode(Code); + auto TU = ASTUnit->getASTContext().getTranslationUnitDecl(); + ClangDocSerializeTestVisitor Visitor(EmittedInfos, Public); + Visitor.TraverseTranslationUnitDecl(TU); + ASSERT_EQ(NumExpectedInfos, EmittedInfos.size()); +} + +void ExtractInfosFromCodeWithArgs(StringRef Code, size_t NumExpectedInfos, bool Public, + EmittedInfoList , std::vector& Args) { + auto ASTUnit = clang::tooling::buildASTFromCodeWithArgs(Code, Args); + auto TU = ASTUnit->getASTContext().getTranslationUnitDecl(); + ClangDocSerializeTestVisitor Visitor(EmittedInfos, Public); + Visitor.TraverseTranslationUnitDecl(TU); + ASSERT_EQ(NumExpectedInfos, EmittedInfos.size()); +} + +// Test serialization of namespace declarations. +TEST(SerializeTest, emitNamespaceInfo) { + EmittedInfoList Infos; + ExtractInfosFromCode("namespace A { namespace B { void f() {} } }", 3, + /*Public=*/false, Infos); + + NamespaceInfo *A = InfoAsNamespace(Infos[0].get()); + NamespaceInfo ExpectedA(EmptySID, "A"); + CheckNamespaceInfo(, A); + + NamespaceInfo *B = InfoAsNamespace(Infos[1].get()); + NamespaceInfo ExpectedB(EmptySID, "B"); + ExpectedB.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace); + CheckNamespaceInfo(, B); + + NamespaceInfo *BWithFunction = InfoAsNamespace(Infos[2].get()); + NamespaceInfo ExpectedBWithFunction(EmptySID); + FunctionInfo F; +