From b75c7c8388852eb7fb01e5e11efc31d1df8b120e Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Fri, 10 Feb 2023 09:36:14 -0800 Subject: [PATCH] App: Add basic test for new Metadata code --- src/App/Metadata.cpp | 13 ++- src/App/Metadata.h | 4 +- tests/src/App/CMakeLists.txt | 1 + tests/src/App/Metadata.cpp | 190 +++++++++++++++++++++++++++++++++++ 4 files changed, 205 insertions(+), 3 deletions(-) create mode 100644 tests/src/App/Metadata.cpp diff --git a/src/App/Metadata.cpp b/src/App/Metadata.cpp index 2504924797..5d6b55949c 100644 --- a/src/App/Metadata.cpp +++ b/src/App/Metadata.cpp @@ -126,7 +126,9 @@ App::Metadata::Metadata(const std::string& rawData) : _dom(nullptr) { MemBufInputSource buffer( - reinterpret_cast(rawData.c_str()), rawData.size(), "raw data (in memory)"); + reinterpret_cast(rawData.c_str()), + rawData.size(), + "raw data (in memory)"); loadFromInputSource(buffer); } @@ -957,6 +959,9 @@ Meta::Contact::Contact(std::string name, std::string email) Meta::Contact::Contact(const XERCES_CPP_NAMESPACE::DOMElement* elem) { + if (!elem){ + return; + } auto emailAttribute = elem->getAttribute(XUTF8Str("email").unicodeForm()); name = StrXUTF8(elem->getTextContent()).str; email = StrXUTF8(emailAttribute).str; @@ -976,6 +981,9 @@ Meta::License::License(std::string name, fs::path file) Meta::License::License(const XERCES_CPP_NAMESPACE::DOMElement* elem) { + if (!elem){ + return; + } auto fileAttribute = elem->getAttribute(XUTF8Str("file").unicodeForm()); if (XMLString::stringLen(fileAttribute) > 0) { file = fs::path(StrXUTF8(fileAttribute).str); @@ -1002,6 +1010,9 @@ Meta::Url::Url(std::string location, UrlType type) Meta::Url::Url(const XERCES_CPP_NAMESPACE::DOMElement* elem) { + if (!elem) { + return; + } auto typeAttribute = StrXUTF8(elem->getAttribute(XUTF8Str("type").unicodeForm())).str; if (typeAttribute.empty() || typeAttribute == "website") { type = UrlType::website; diff --git a/src/App/Metadata.h b/src/App/Metadata.h index dd426b6943..38c936e361 100644 --- a/src/App/Metadata.h +++ b/src/App/Metadata.h @@ -64,7 +64,7 @@ struct AppExport Contact { */ struct AppExport License { License() = default; - License(std::string name, boost::filesystem::path file); + License(std::string name, boost::filesystem::path file); explicit License(const XERCES_CPP_NAMESPACE::DOMElement* elem); std::string name;//< Short name of license, e.g. "LGPL2", "MIT", "Mozilla Public License", etc. boost::filesystem::path @@ -88,7 +88,7 @@ enum class UrlType */ struct AppExport Url { Url(); - Url(std::string location, UrlType type); + Url(std::string location, UrlType type); explicit Url(const XERCES_CPP_NAMESPACE::DOMElement* elem); std::string location;//< The actual URL, including protocol UrlType type; //< What kind of URL this is diff --git a/tests/src/App/CMakeLists.txt b/tests/src/App/CMakeLists.txt index 6cc3e36166..32ea6d672c 100644 --- a/tests/src/App/CMakeLists.txt +++ b/tests/src/App/CMakeLists.txt @@ -2,4 +2,5 @@ target_sources( Tests_run PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Branding.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Metadata.cpp ) diff --git a/tests/src/App/Metadata.cpp b/tests/src/App/Metadata.cpp new file mode 100644 index 0000000000..59fe73923d --- /dev/null +++ b/tests/src/App/Metadata.cpp @@ -0,0 +1,190 @@ +#include "gtest/gtest.h" + +#include "App/Metadata.h" + +TEST(ContactTest, ContactDefaultConstruction){ + auto contact = App::Meta::Contact(); + ASSERT_EQ(contact.name,""); + ASSERT_EQ(contact.email,""); +} + +TEST(ContactTest, ContactParameterConstruction){ + auto contact = App::Meta::Contact("Name","email@some.com"); + ASSERT_EQ(contact.name,"Name"); + ASSERT_EQ(contact.email,"email@some.com"); +} + +TEST(ContactTest, ContactNullDomNodeConstruction){ + auto contact = App::Meta::Contact(nullptr); + ASSERT_EQ(contact.name,""); + ASSERT_EQ(contact.email,""); +} + +TEST(ContactTest, ContactOperatorEquality){ + auto contact1 = App::Meta::Contact("Name","Email"); + auto contact2 = App::Meta::Contact("Name","Email"); + auto contact3 = App::Meta::Contact("NotName","Email"); + auto contact4 = App::Meta::Contact("Name","NotEmail"); + ASSERT_TRUE(contact1 == contact2); + ASSERT_FALSE(contact1 == contact3); + ASSERT_FALSE(contact1 == contact4); +} + +TEST(LicenseTest, LicenseDefaultConstruction){ + auto contact = App::Meta::License(); + ASSERT_EQ(contact.name,""); + ASSERT_EQ(contact.file,""); +} + +TEST(LicenseTest, LicenseParameterConstruction){ + auto contact = App::Meta::License("Name","path/to/file"); + ASSERT_EQ(contact.name,"Name"); + ASSERT_EQ(contact.file,"path/to/file"); +} + +TEST(LicenseTest, LicenseNullDomNodeConstruction){ + auto contact = App::Meta::License(nullptr); + ASSERT_EQ(contact.name,""); + ASSERT_EQ(contact.file,""); +} + +TEST(LicenseTest, LicenseOperatorEquality){ + auto license1 = App::Meta::License("Name","path/to/file"); + auto license2 = App::Meta::License("Name","path/to/file"); + auto license3 = App::Meta::License("NotName","path/to/file"); + auto license4 = App::Meta::License("Name","not/path/to/file"); + ASSERT_TRUE(license1 == license2); + ASSERT_FALSE(license1 == license3); + ASSERT_FALSE(license1 == license4); +} + +TEST(UrlTest, UrlDefaultConstruction){ + auto url = App::Meta::Url(); + ASSERT_EQ(url.location,""); + ASSERT_EQ(url.type,App::Meta::UrlType::website); +} + +TEST(UrlTest, UrlParameterConstruction){ + auto url = App::Meta::Url("https://some.url",App::Meta::UrlType::documentation); + ASSERT_EQ(url.location,"https://some.url"); + ASSERT_EQ(url.type,App::Meta::UrlType::documentation); +} + +TEST(UrlTest, UrlNullDomNodeConstruction){ + auto url = App::Meta::Url(nullptr); + ASSERT_EQ(url.location,""); +} + +TEST(UrlTest, UrlOperatorEquality){ + auto url1 = App::Meta::Url("https://some.url",App::Meta::UrlType::documentation); + auto url2 = App::Meta::Url("https://some.url",App::Meta::UrlType::documentation); + auto url3 = App::Meta::Url("https://not.some.url",App::Meta::UrlType::documentation); + auto url4 = App::Meta::Url("https://some.url",App::Meta::UrlType::website); + ASSERT_TRUE(url1 == url2); + ASSERT_FALSE(url1 == url3); + ASSERT_FALSE(url1 == url4); +} + +TEST(VersionTest, VersionDefaultConstruction){ + auto version = App::Meta::Version(); + ASSERT_EQ(version.major, 0); + ASSERT_EQ(version.minor, 0); + ASSERT_EQ(version.patch, 0); + ASSERT_EQ(version.suffix, ""); +} + +TEST(VersionTest, VersionParameterConstruction){ + auto version = App::Meta::Version(1,2,3,"delta"); + ASSERT_EQ(version.major, 1); + ASSERT_EQ(version.minor, 2); + ASSERT_EQ(version.patch, 3); + ASSERT_EQ(version.suffix, "delta"); +} + +TEST(VersionTest, VersionStringConstruction){ + auto version = App::Meta::Version("1.2.3delta"); + ASSERT_EQ(version.major, 1); + ASSERT_EQ(version.minor, 2); + ASSERT_EQ(version.patch, 3); + ASSERT_EQ(version.suffix, "delta"); +} + +TEST(VersionTest, VersionOperatorEqual){ + auto version1 = App::Meta::Version(1,2,3,"delta"); + auto version2 = App::Meta::Version(1,2,3,"delta"); + auto version3 = App::Meta::Version(1,3,3,"delta"); + auto version4 = App::Meta::Version(1,2,4,"delta"); + auto version5 = App::Meta::Version(1,2,3,"gamma"); + ASSERT_EQ(version1, version2); + ASSERT_NE(version1, version3); + ASSERT_NE(version1, version4); + ASSERT_NE(version1, version5); +} + +TEST(VersionTest, VersionOperatorComparison){ + auto version_2_3_4_delta = App::Meta::Version(2,3,4,"delta"); + auto version_1_3_4_delta = App::Meta::Version(1,3,4,"delta"); + auto version_3_3_4_delta = App::Meta::Version(3,3,4,"delta"); + auto version_2_2_4_delta = App::Meta::Version(2,2,4,"delta"); + auto version_2_4_4_delta = App::Meta::Version(2,4,4,"delta"); + auto version_2_3_3_delta = App::Meta::Version(2,3,3,"delta"); + auto version_2_3_5_delta = App::Meta::Version(2,3,5,"delta"); + auto version_2_3_4_epsilon = App::Meta::Version(2,3,4,"epsilon"); + auto version_2_3_4_beta = App::Meta::Version(2,3,4,"beta"); + ASSERT_GT(version_2_3_4_delta, version_1_3_4_delta); + ASSERT_LT(version_2_3_4_delta, version_3_3_4_delta); + ASSERT_GT(version_2_3_4_delta, version_2_2_4_delta); + ASSERT_LT(version_2_3_4_delta, version_2_4_4_delta); + ASSERT_GT(version_2_3_4_delta, version_2_3_3_delta); + ASSERT_LT(version_2_3_4_delta, version_2_3_5_delta); + ASSERT_GT(version_2_3_4_delta, version_2_3_4_beta); + ASSERT_LT(version_2_3_4_delta, version_2_3_4_epsilon); +} + +// TODO: Test Dependency +// TODO: Test GenericMetadata + +class MetadataTest : public ::testing::Test { +protected: + void SetUp() override { + try { + xercesc_3_2::XMLPlatformUtils::Initialize(); + } + catch (const xercesc_3_2::XMLException& toCatch) { + // Some kind of Google Test error condition? + } + } + void TearDown() override { + xercesc_3_2::XMLPlatformUtils::Terminate(); + } + std::string GivenSimpleMetadataXMLString() + { + std::stringstream stream; + stream << "\n" + << "\n" + << " " << _name << "\n" + << " " << _description << "\n" + << " " << _version << "\n" + << " 2022-01-07\n" + << " https://github.com/FreeCAD/FreeCAD\n" + << ""; + return stream.str(); + } + + void AssertMetadataMatches(App::Metadata &testObject) { + ASSERT_EQ(testObject.name(), _name); + ASSERT_EQ(testObject.description(), _description); + ASSERT_EQ(testObject.version(), App::Meta::Version(_version)); + } + + std::string _name = "TestAddon"; + std::string _description = "A package.xml file for unit testing."; + std::string _version = "1.2.3beta"; +}; + +TEST_F(MetadataTest, MetadataInMemoryConstruction) { + auto xml = GivenSimpleMetadataXMLString(); + auto testObject = App::Metadata(std::string{xml}); + AssertMetadataMatches(testObject); +} +