From 0a5e59adae70878e5d89d40e76169889ed4fe6fe Mon Sep 17 00:00:00 2001 From: berniev Date: Thu, 23 Feb 2023 03:34:30 +1000 Subject: [PATCH] an example of using constexpr array for data simplifies code and removes the need for a class. --- src/App/CMakeLists.txt | 1 - src/App/Document.cpp | 63 ++++++++++----- src/App/Document.h | 7 +- src/App/License.cpp | 115 --------------------------- src/App/License.h | 85 +++++++++----------- src/Gui/DlgProjectInformationImp.cpp | 29 +++---- src/Gui/DlgSettingsDocumentImp.cpp | 29 ++++--- tests/src/App/License.cpp | 83 ++++--------------- 8 files changed, 132 insertions(+), 280 deletions(-) delete mode 100644 src/App/License.cpp diff --git a/src/App/CMakeLists.txt b/src/App/CMakeLists.txt index 6a7d98df24..02ebe92de2 100644 --- a/src/App/CMakeLists.txt +++ b/src/App/CMakeLists.txt @@ -166,7 +166,6 @@ SET(Document_CPP_SRCS TextDocument.cpp Link.cpp LinkBaseExtensionPyImp.cpp - License.cpp License.h ) diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 45833c1253..d9b1e2bcdf 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -779,8 +779,8 @@ void Document::setTransactionMode(int iMode) //-------------------------------------------------------------------------- // constructor //-------------------------------------------------------------------------- -Document::Document(const char *name) - : myName(name) +Document::Document(const char* documentName) + : myName(documentName) { // Remark: In a constructor we should never increment a Python object as we cannot be sure // if the Python interpreter gets a reference of it. E.g. if we increment but Python don't @@ -795,15 +795,29 @@ Document::Document(const char *name) Console().Log("+App::Document: %p\n", this); #endif std::string CreationDateString = Base::TimeInfo::currentDateTimeString(); - std::string Author = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Document")->GetASCII("prefAuthor", ""); - std::string AuthorComp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Document")->GetASCII("prefCompany", ""); + std::string Author = App::GetApplication() + .GetParameterGroupByPath("User parameter:BaseApp/Preferences/Document") + ->GetASCII("prefAuthor", ""); + std::string AuthorComp = + App::GetApplication() + .GetParameterGroupByPath("User parameter:BaseApp/Preferences/Document") + ->GetASCII("prefCompany", ""); ADD_PROPERTY_TYPE(Label, ("Unnamed"), 0, Prop_None, "The name of the document"); - ADD_PROPERTY_TYPE(FileName, (""), 0, PropertyType(Prop_Transient | Prop_ReadOnly), "The path to the file where the document is saved to"); + ADD_PROPERTY_TYPE(FileName, + (""), + 0, + PropertyType(Prop_Transient | Prop_ReadOnly), + "The path to the file where the document is saved to"); ADD_PROPERTY_TYPE(CreatedBy, (Author.c_str()), 0, Prop_None, "The creator of the document"); - ADD_PROPERTY_TYPE(CreationDate, (CreationDateString.c_str()), 0, Prop_ReadOnly, "Date of creation"); + ADD_PROPERTY_TYPE( + CreationDate, (CreationDateString.c_str()), 0, Prop_ReadOnly, "Date of creation"); ADD_PROPERTY_TYPE(LastModifiedBy, (""), 0, Prop_None, 0); ADD_PROPERTY_TYPE(LastModifiedDate, ("Unknown"), 0, Prop_ReadOnly, "Date of last modification"); - ADD_PROPERTY_TYPE(Company, (AuthorComp.c_str()), 0, Prop_None, "Additional tag to save the name of the company"); + ADD_PROPERTY_TYPE(Company, + (AuthorComp.c_str()), + 0, + Prop_None, + "Additional tag to save the name of the company"); ADD_PROPERTY_TYPE(Comment, (""), 0, Prop_None, "Additional tag to save a comment"); ADD_PROPERTY_TYPE(Meta, (), 0, Prop_None, "Map with additional meta information"); ADD_PROPERTY_TYPE(Material, (), 0, Prop_None, "Map with material properties"); @@ -813,23 +827,34 @@ Document::Document(const char *name) ADD_PROPERTY_TYPE(Uid, (id), 0, Prop_ReadOnly, "UUID of the document"); // license stuff - long licenseId = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Document")->GetInt("prefLicenseType", 0); - App::License licenseType{licenseId}; - std::string license = licenseType.getLicense(); - std::string licenseUrl = licenseType.getUrl(); - licenseUrl = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Document")->GetASCII("prefLicenseUrl", licenseUrl.c_str()); + auto paramGrp {App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/Document")}; + auto index = static_cast(paramGrp->GetInt("prefLicenseType", 0)); + const char* name = App::licenseItems.at(index).at(App::posnOfFullName); + const char* url = App::licenseItems.at(index).at(App::posnOfUrl); + std::string licenseUrl = (paramGrp->GetASCII("prefLicenseUrl", url)); - ADD_PROPERTY_TYPE(License, (license.c_str()), 0, Prop_None, "License string of the Item"); - ADD_PROPERTY_TYPE(LicenseURL, (licenseUrl.c_str()), 0, Prop_None, "URL to the license text/contract"); - ADD_PROPERTY_TYPE(ShowHidden, (false), 0, PropertyType(Prop_None), + ADD_PROPERTY_TYPE(License, (name), 0, Prop_None, "License string of the Item"); + ADD_PROPERTY_TYPE( + LicenseURL, (licenseUrl.c_str()), 0, Prop_None, "URL to the license text/contract"); + ADD_PROPERTY_TYPE(ShowHidden, + (false), + 0, + PropertyType(Prop_None), "Whether to show hidden object items in the tree view"); // this creates and sets 'TransientDir' in onChanged() - ADD_PROPERTY_TYPE(TransientDir, (""), 0, PropertyType(Prop_Transient | Prop_ReadOnly), + ADD_PROPERTY_TYPE(TransientDir, + (""), + 0, + PropertyType(Prop_Transient | Prop_ReadOnly), "Transient directory, where the files live while the document is open"); - ADD_PROPERTY_TYPE(Tip, (nullptr), 0, PropertyType(Prop_Transient), - "Link of the tip object of the document"); - ADD_PROPERTY_TYPE(TipName, (""), 0, PropertyType(Prop_Hidden | Prop_ReadOnly), + ADD_PROPERTY_TYPE( + Tip, (nullptr), 0, PropertyType(Prop_Transient), "Link of the tip object of the document"); + ADD_PROPERTY_TYPE(TipName, + (""), + 0, + PropertyType(Prop_Hidden | Prop_ReadOnly), "Link of the tip object of the document"); Uid.touch(); } diff --git a/src/App/Document.h b/src/App/Document.h index f0d7cabfc0..f09a7310d0 100644 --- a/src/App/Document.h +++ b/src/App/Document.h @@ -98,10 +98,7 @@ public: PropertyString Id; /// unique identifier of the document PropertyUUID Uid; - /** License string - * Holds the short license string for the Item, e.g. CC-BY - * for the Creative Commons license suit. - */ + /// Full name of the licence e.g. "Creative Commons Attribution". See https://spdx.org/licenses/ App::PropertyString License; /// License description/contract URL App::PropertyString LicenseURL; @@ -520,7 +517,7 @@ public: protected: /// Construction - explicit Document(const char *name = ""); + explicit Document(const char *documentName = ""); void _removeObject(DocumentObject* pcObject); void _addObject(DocumentObject* pcObject, const char* pObjectName); diff --git a/src/App/License.cpp b/src/App/License.cpp deleted file mode 100644 index cd772c56aa..0000000000 --- a/src/App/License.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2023 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#include "PreCompiled.h" -#ifndef _PreComp_ -# include -# include -#endif - -#include "License.h" - -using namespace App; - -std::map License::licenseItems; - -License::License(License::Type type) - : type{type} -{ - init(); -} - -License::License(long id) - : type{static_cast(id)} -{ - if (id < 0 || id > static_cast(Type::Other)) { - type = Type::Other; - } - - init(); -} - -License::License(int id) - : License(static_cast(id)) -{ -} - -void License::init() -{ - static bool first = true; - if (!first) - return; - first = false; - - licenseItems[Type::AllRightsReserved] = LicenseItem{"All rights reserved", - "https://en.wikipedia.org/wiki/All_rights_reserved"}; - licenseItems[Type::CC_BY_40] = LicenseItem{"Creative Commons Attribution", - "https://creativecommons.org/licenses/by/4.0/"}; - licenseItems[Type::CC_BY_SA_40] = LicenseItem{"Creative Commons Attribution-ShareAlike", - "https://creativecommons.org/licenses/by-sa/4.0/"}; - licenseItems[Type::CC_BY_ND_40] = LicenseItem{"Creative Commons Attribution-NoDerivatives", - "https://creativecommons.org/licenses/by-nd/4.0/"}; - licenseItems[Type::CC_BY_NC_40] = LicenseItem{"Creative Commons Attribution-NonCommercial", - "https://creativecommons.org/licenses/by-nc/4.0/"}; - licenseItems[Type::CC_BY_NC_SA_40] = LicenseItem{"Creative Commons Attribution-NonCommercial-ShareAlike", - "https://creativecommons.org/licenses/by-nc-sa/4.0/"}; - licenseItems[Type::CC_BY_NC_ND_40] = LicenseItem{"Creative Commons Attribution-NonCommercial-NoDerivatives", - "https://creativecommons.org/licenses/by-nc-nd/4.0/"}; - licenseItems[Type::PublicDomain] = LicenseItem{"Public Domain", - "https://en.wikipedia.org/wiki/Public_domain"}; - licenseItems[Type::FreeArt] = LicenseItem{"FreeArt", "https://artlibre.org/licence/lal"}; - licenseItems[Type::CERN_OHS_S] = LicenseItem{"CERN Open Hardware Licence strongly-reciprocal", - "https://cern-ohl.web.cern.ch/"}; - licenseItems[Type::CERN_OHS_W] = LicenseItem{"CERN Open Hardware Licence weakly-reciprocal", - "https://cern-ohl.web.cern.ch/"}; - licenseItems[Type::CERN_OHS_P] = LicenseItem{"CERN Open Hardware Licence permissive", - "https://cern-ohl.web.cern.ch/"}; - licenseItems[Type::Other] = LicenseItem{"Other", ""}; -} - -License::Type License::getType() const -{ - return type; -} - -std::string License::getLicense() const -{ - return licenseItems.at(type).license; -} - -std::string License::getUrl() const -{ - return licenseItems.at(type).url; -} - -std::vector License::getLicenses() -{ - init(); - std::vector output; - output.reserve(licenseItems.size()); - using Value = std::pair; - std::transform(licenseItems.cbegin(), licenseItems.cend(), std::back_inserter(output), [](const Value& val) { - return val.second.license; - }); - - return output; -} diff --git a/src/App/License.h b/src/App/License.h index 68f47189d8..ad837c591b 100644 --- a/src/App/License.h +++ b/src/App/License.h @@ -24,57 +24,48 @@ #define APP_LICENSE_H #include +#include #include -#include -#include -namespace App { - -/*! - * \brief The License class - * Handling of standard licenses. - */ -class License +namespace App { -public: - enum class Type { - AllRightsReserved, - CC_BY_40, - CC_BY_SA_40, - CC_BY_ND_40, - CC_BY_NC_40, - CC_BY_NC_SA_40, - CC_BY_NC_ND_40, - PublicDomain, - FreeArt, - CERN_OHS_S, - CERN_OHS_W, - CERN_OHS_P, - Other - }; - AppExport explicit License(Type); - AppExport explicit License(long); - AppExport explicit License(int); - AppExport Type getType() const; - AppExport std::string getLicense() const; - AppExport std::string getUrl() const; - - AppExport static std::vector getLicenses(); - -private: - static void init(); - - struct LicenseItem - { - std::string license; - std::string url; - }; - Type type; - - static std::map licenseItems; -}; +/** + * Licenses data [identifier, fullName, url] + * See also https://spdx.org/licenses/ + */ +constexpr int colsInArray = 3; +using TLicenseArr = std::array; +constexpr int posnOfIdentifier = 0; +constexpr int posnOfFullName = 1; +constexpr int posnOfUrl = 2; +constexpr int countOfLicenses {12}; +// clang-format off +constexpr std::array licenseItems {{ + { "AllRightsReserved", "All rights reserved", "https://en.wikipedia.org/wiki/All_rights_reserved" }, + { "CC_BY_40", "Creative Commons Attribution", "https://creativecommons.org/licenses/by/4.0/" }, + { "CC_BY_SA_40", "Creative Commons Attribution-ShareAlike", "https://creativecommons.org/licenses/by-sa/4.0/" }, + { "CC_BY_ND_40", "Creative Commons Attribution-NoDerivatives", "https://creativecommons.org/licenses/by-nd/4.0/" }, + { "CC_BY_NC_40", "Creative Commons Attribution-NonCommercial", "https://creativecommons.org/licenses/by-nc/4.0/" }, + { "CC_BY_NC_SA_40", "Creative Commons Attribution-NonCommercial-ShareAlike", "https://creativecommons.org/licenses/by-nc-sa/4.0/" }, + { "CC_BY_NC_ND_40", "Creative Commons Attribution-NonCommercial-NoDerivatives", "https://creativecommons.org/licenses/by-nc-nd/4.0/" }, + { "PublicDomain", "Public Domain", "https://en.wikipedia.org/wiki/Public_domain" }, + { "FreeArt", "FreeArt", "https://artlibre.org/licence/lal" }, + { "CERN_OHS_S", "CERN Open Hardware Licence strongly-reciprocal", "https://cern-ohl.web.cern.ch/" }, + { "CERN_OHS_W", "CERN Open Hardware Licence weakly-reciprocal", "https://cern-ohl.web.cern.ch/" }, + { "CERN_OHS_P", "CERN Open Hardware Licence permissive", "https://cern-ohl.web.cern.ch/" }, +}}; +// clang-format on +int constexpr findLicense(const char* identifier) +{ + for (int i = 0; i < countOfLicenses; i++) { + if (licenseItems.at(i).at(posnOfIdentifier) == identifier) { + return i; + } + } + return -1; } +}// namespace App -#endif // APP_LICENSE_H +#endif// APP_LICENSE_H diff --git a/src/Gui/DlgProjectInformationImp.cpp b/src/Gui/DlgProjectInformationImp.cpp index 978b1b700e..9c794844bd 100644 --- a/src/Gui/DlgProjectInformationImp.cpp +++ b/src/Gui/DlgProjectInformationImp.cpp @@ -76,12 +76,14 @@ DlgProjectInformationImp::DlgProjectInformationImp(App::Document* doc, QWidget* ui->lineEditLastModDate->setText(QString::fromUtf8(doc->LastModifiedDate.getValue())); ui->lineEditCompany->setText(QString::fromUtf8(doc->Company.getValue())); - auto rawLicenses = App::License::getLicenses(); - for (const auto& it : rawLicenses) { - QString text = QApplication::translate("Gui::Dialog::DlgSettingsDocument", it.c_str()); - ui->comboLicense->addItem(text, QByteArray(it.c_str())); + // load comboBox with license names + for (const auto& item : App::licenseItems) { + const char* name {item.at(App::posnOfFullName)}; + QString translated = QApplication::translate("Gui::Dialog::DlgSettingsDocument", name); + ui->comboLicense->addItem(translated, QByteArray(name)); } + // set default position to match document int index = ui->comboLicense->findData(QByteArray(doc->License.getValue())); if (index >= 0) { ui->comboLicense->setCurrentIndex(index); @@ -128,10 +130,12 @@ void DlgProjectInformationImp::accept() _doc->CreatedBy.setValue(ui->lineEditCreator->text().toUtf8()); _doc->LastModifiedBy.setValue(ui->lineEditCreator->text().toUtf8()); _doc->Company.setValue(ui->lineEditCompany->text().toUtf8()); - QByteArray license = ui->comboLicense->itemData(ui->comboLicense->currentIndex()).toByteArray(); - if (license.isEmpty()) - license = ui->comboLicense->itemText(ui->comboLicense->currentIndex()).toUtf8(); - _doc->License.setValue(license); + QByteArray licenseName {ui->comboLicense->currentData().toByteArray()}; + // Is this really necessary? + if (licenseName.isEmpty()) { + licenseName = ui->comboLicense->currentText().toUtf8(); + } + _doc->License.setValue(licenseName); _doc->LicenseURL.setValue(ui->lineEditLicenseURL->text().toUtf8()); // Replace newline escape sequence through '\\n' string @@ -149,13 +153,10 @@ void DlgProjectInformationImp::accept() void DlgProjectInformationImp::onLicenseTypeChanged(int index) { - App::License license{index}; - std::string url = license.getUrl(); - if (license.getType() == App::License::Type::Other) { - url = _doc->LicenseURL.getValue(); - } + const char* url {index >= 0 && index < App::countOfLicenses ? App::licenseItems.at(index).at(App::posnOfUrl) + : _doc->LicenseURL.getValue()}; - ui->lineEditLicenseURL->setText(QString::fromStdString(url)); + ui->lineEditLicenseURL->setText(QString::fromLatin1(url)); } /** diff --git a/src/Gui/DlgSettingsDocumentImp.cpp b/src/Gui/DlgSettingsDocumentImp.cpp index c41d9ebef0..7c788bb2df 100644 --- a/src/Gui/DlgSettingsDocumentImp.cpp +++ b/src/Gui/DlgSettingsDocumentImp.cpp @@ -151,28 +151,33 @@ void DlgSettingsDocumentImp::changeEvent(QEvent *e) void DlgSettingsDocumentImp::addLicenseTypes() { + auto add = [&](const char* what) { + ui->prefLicenseType->addItem( + QApplication::translate("Gui::Dialog::DlgSettingsDocument", what)); + }; + ui->prefLicenseType->clear(); - auto rawLicenses = App::License::getLicenses(); - for (const auto& it : rawLicenses) { - QString text = QApplication::translate("Gui::Dialog::DlgSettingsDocument", it.c_str()); - ui->prefLicenseType->addItem(text); + for (const auto& licenseItem : App::licenseItems) { + add(licenseItem.at(App::posnOfFullName)); } + add("Other"); } /** - * Set the correct URL depending on the license type + * Fix Url according to changed type */ void DlgSettingsDocumentImp::onLicenseTypeChanged(int index) { - App::License license{index}; - std::string url = license.getUrl(); - if (license.getType() == App::License::Type::Other) { - ui->prefLicenseUrl->clear(); - ui->prefLicenseUrl->setReadOnly(false); + if (index >= 0 && index < App::countOfLicenses) { + // existing license + const char* url {App::licenseItems.at(index).at(App::posnOfUrl)}; + ui->prefLicenseUrl->setText(QString::fromLatin1(url)); + ui->prefLicenseUrl->setReadOnly(true); } else { - ui->prefLicenseUrl->setReadOnly(true); - ui->prefLicenseUrl->setText(QString::fromStdString(url)); + // Other + ui->prefLicenseUrl->clear(); + ui->prefLicenseUrl->setReadOnly(false); } } diff --git a/tests/src/App/License.cpp b/tests/src/App/License.cpp index 009a93c1eb..c6aa3501ae 100644 --- a/tests/src/App/License.cpp +++ b/tests/src/App/License.cpp @@ -2,83 +2,32 @@ #include "App/License.h" -TEST(License, AllRightsReserved) +TEST(License, isLicenseYesStr) { - auto lic = App::License{App::License::Type::AllRightsReserved}; - ASSERT_EQ(lic.getType(), App::License::Type::AllRightsReserved); - ASSERT_EQ(lic.getLicense(), "All rights reserved"); - ASSERT_EQ(lic.getUrl(), "https://en.wikipedia.org/wiki/All_rights_reserved"); + EXPECT_EQ(App::findLicense("CC_BY_40"), 1); } -TEST(License, CC_BY_40) +TEST(License, UnknownIdentifier) { - auto lic = App::License{App::License::Type::CC_BY_40}; - ASSERT_EQ(lic.getType(), App::License::Type::CC_BY_40); - ASSERT_EQ(lic.getLicense(), "Creative Commons Attribution"); - ASSERT_EQ(lic.getUrl(), "https://creativecommons.org/licenses/by/4.0/"); + int index {App::findLicense("junk")}; + EXPECT_EQ(index, -1); } -TEST(License, CC_BY_SA_40) +TEST(License, direct) { - auto lic = App::License{App::License::Type::CC_BY_SA_40}; - ASSERT_EQ(lic.getType(), App::License::Type::CC_BY_SA_40); - ASSERT_EQ(lic.getLicense(), "Creative Commons Attribution-ShareAlike"); - ASSERT_EQ(lic.getUrl(), "https://creativecommons.org/licenses/by-sa/4.0/"); + int posn {App::findLicense("CC_BY_40")}; + App::TLicenseArr tt { + "CC_BY_40", "Creative Commons Attribution", "https://creativecommons.org/licenses/by/4.0/"}; + EXPECT_EQ(App::licenseItems.at(posn), tt); } -TEST(License, PublicDomain) +TEST(License, findLicenseByIdent) { - auto lic = App::License{App::License::Type::PublicDomain}; - ASSERT_EQ(lic.getType(), App::License::Type::PublicDomain); - ASSERT_EQ(lic.getLicense(), "Public Domain"); - ASSERT_EQ(lic.getUrl(), "https://en.wikipedia.org/wiki/Public_domain"); + App::TLicenseArr arr {App::licenseItems.at(App::findLicense("CC_BY_40"))}; + + EXPECT_STREQ(arr.at(App::posnOfIdentifier), "CC_BY_40"); + EXPECT_STREQ(arr.at(App::posnOfFullName), "Creative Commons Attribution"); + EXPECT_STREQ(arr.at(App::posnOfUrl), "https://creativecommons.org/licenses/by/4.0/"); } -TEST(License, FreeArt) -{ - auto lic = App::License{App::License::Type::FreeArt}; - ASSERT_EQ(lic.getType(), App::License::Type::FreeArt); - ASSERT_EQ(lic.getLicense(), "FreeArt"); - ASSERT_EQ(lic.getUrl(), "https://artlibre.org/licence/lal"); -} -TEST(License, CERN_OHS_S) -{ - auto lic = App::License{App::License::Type::CERN_OHS_S}; - ASSERT_EQ(lic.getType(), App::License::Type::CERN_OHS_S); - ASSERT_EQ(lic.getLicense(), "CERN Open Hardware Licence strongly-reciprocal"); - ASSERT_EQ(lic.getUrl(), "https://cern-ohl.web.cern.ch/"); -} - -TEST(License, Other) -{ - auto lic = App::License{App::License::Type::Other}; - ASSERT_EQ(lic.getType(), App::License::Type::Other); - ASSERT_EQ(lic.getLicense(), "Other"); - ASSERT_EQ(lic.getUrl(), ""); -} - -TEST(License, CompareTypeWithInt) -{ - auto lic1 = App::License{App::License::Type::Other}; - auto lic2 = App::License{static_cast(App::License::Type::Other)}; - ASSERT_EQ(lic1.getType(), lic2.getType()); -} - -TEST(License, CompareTypeWithLong) -{ - auto lic1 = App::License{App::License::Type::CC_BY_NC_ND_40}; - auto lic2 = App::License{static_cast(App::License::Type::CC_BY_NC_ND_40)}; - ASSERT_EQ(lic1.getType(), lic2.getType()); -} - -TEST(License, All) -{ - std::vector all = App::License::getLicenses(); - int num = static_cast(all.size()); - for (int index = 0; index < num; index++) { - auto lic = App::License{index}; - auto text = all.at(index); - ASSERT_EQ(lic.getLicense(), text); - } -}