reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

commit 6e5a7ebb5e158b50a36d5c8f8a1e33987a5242eb
parent 85bc759a8730d4de1d897c729e7bd05206b7bcb5
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Wed, 25 Nov 2015 20:24:00 -0500

implement another part of the xml database parser

Diffstat:
Msrc/database.cpp | 32++++++++++++++++++++++++++------
Msrc/database.hpp | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/database_v1.cpp | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Mtest/database.cpp | 36++++++++++++++++++++++++++++++++++++
Mtest/database_v1.cpp | 42++++++++++++++++++++++++++++++++++++++++++
Atest/db/v1/anonymous_package.xml | 6++++++
Atest/db/v1/empty_category.xml | 3+++
Atest/db/v1/invalid_type.xml | 6++++++
Mtest/db/v1/unnamed_category.xml | 1+
Atest/db/v1/unnamed_package.xml | 6++++++
Atest/db/v1/wrong_category_tag.xml | 3+++
11 files changed, 254 insertions(+), 14 deletions(-)

diff --git a/src/database.cpp b/src/database.cpp @@ -2,8 +2,6 @@ #include <WDL/tinyxml/tinyxml.h> -#include <cstdio> - DatabasePtr Database::load(const char *file, const char **error) { TiXmlDocument doc(file); @@ -38,12 +36,34 @@ DatabasePtr Database::load(const char *file, const char **error) } } -Database::Database() +void Database::addCategory(CategoryPtr cat) +{ + m_categories.push_back(cat); +} + +Category::Category(const std::string &name) + : m_name(name) +{ +} + +void Category::addPackage(PackagePtr pack) +{ + pack->setCategory(this); + m_packages.push_back(pack); +} + +Package::Type Package::convertType(const char *type) { - printf("constructed\n"); + if(!type) + return UnknownType; + + if(!strcmp(type, "script")) + return ScriptType; + + return UnknownType; } -Database::~Database() +Package::Package() + : m_category(0) { - printf("destructed\n"); } diff --git a/src/database.hpp b/src/database.hpp @@ -2,21 +2,73 @@ #define REAPACK_DATABASE_HPP #include <memory> +#include <string> +#include <vector> class TiXmlElement; class Database; typedef std::shared_ptr<Database> DatabasePtr; +class Category; +typedef std::shared_ptr<Category> CategoryPtr; + +class Package; +typedef std::shared_ptr<Package> PackagePtr; + class Database { public: static DatabasePtr load(const char *, const char **error); - Database(); - ~Database(); + void addCategory(CategoryPtr cat); + const std::vector<CategoryPtr> &categories() const { return m_categories; } + CategoryPtr category(const int i) const { return m_categories[i]; } private: + friend Category; static DatabasePtr loadV1(TiXmlElement *, const char **); + + std::vector<CategoryPtr> m_categories; +}; + +class Category { +public: + Category(const std::string &name); + + const std::string &name() const { return m_name; } + + void addPackage(PackagePtr pack); + const std::vector<PackagePtr> &packages() const { return m_packages; } + PackagePtr package(const int i) const { return m_packages[i]; } + +private: + friend Package; + friend DatabasePtr Database::loadV1(TiXmlElement *, const char **); + static CategoryPtr loadV1(TiXmlElement *, const char **); + + std::string m_name; + std::vector<PackagePtr> m_packages; +}; + +class Package { +public: + enum Type { + UnknownType, + ScriptType, + }; + + static Type convertType(const char *); + + Package(); + + void setCategory(Category *cat) { m_category = cat; } + Category *category() const { return m_category; } + +private: + friend CategoryPtr Category::loadV1(TiXmlElement *, const char **); + static PackagePtr loadV1(TiXmlElement *, const char **); + + Category *m_category; }; #endif diff --git a/src/database_v1.cpp b/src/database_v1.cpp @@ -2,23 +2,88 @@ #include <WDL/tinyxml/tinyxml.h> +using namespace std; + DatabasePtr Database::loadV1(TiXmlElement *root, const char **error) { - DatabasePtr db = std::make_shared<Database>(); + DatabasePtr db = make_shared<Database>(); // read categories - TiXmlElement *catNode = root->FirstChildElement("category"); + TiXmlElement *catNode = root->FirstChildElement(); while(catNode) { - const char *name = catNode->Attribute("name"); + CategoryPtr cat = Category::loadV1(catNode, error); - if(!name) { - *error = "missing category name"; + if(!cat.get()) return 0; - } + + db->addCategory(cat); catNode = catNode->NextSiblingElement(); } return db; } + +CategoryPtr Category::loadV1(TiXmlElement *catNode, const char **error) +{ + if(strcmp(catNode->Value(), "category")) { + *error = "not a category"; + return 0; + } + + const char *name = catNode->Attribute("name"); + + if(!name || !strlen(name)) { + *error = "missing category name"; + return 0; + } + + CategoryPtr cat = make_shared<Category>(name); + + TiXmlElement *packNode = catNode->FirstChildElement(); + + while(packNode) { + PackagePtr pack = Package::loadV1(packNode, error); + + if(!pack.get()) + return 0; + + cat->addPackage(pack); + + packNode = packNode->NextSiblingElement(); + } + return cat; +} + +PackagePtr Package::loadV1(TiXmlElement *packNode, const char **error) +{ + if(strcmp(packNode->Value(), "reapack")) { + *error = "not a package"; + return 0; + } + + const char *name = packNode->Attribute("name"); + + if(!name || !strlen(name)) { + *error = "missing package name"; + return 0; + } + + const char *typeStr = packNode->Attribute("type"); + const Package::Type type = Package::convertType(typeStr); + + if(type == Package::UnknownType) { + *error = "unsupported package type"; + return 0; + } + + const char *author = packNode->Attribute("author"); + + if(!author || !strlen(author)) { + *error = "package is anonymous"; + return 0; + } + + return 0; +} diff --git a/test/database.cpp b/test/database.cpp @@ -48,3 +48,39 @@ TEST_CASE("future version", M) { CHECK(db.get() == 0); REQUIRE(string(error) == "unsupported version"); } + +TEST_CASE("add category to database", M) { + Database db; + CHECK(db.categories().size() == 0); + + db.addCategory(make_shared<Category>("a")); + + REQUIRE(db.categories().size() == 1); +} + +TEST_CASE("add package to category", M) { + PackagePtr pack = make_shared<Package>(); + + Category cat("a"); + CHECK(cat.packages().size() == 0); + CHECK_FALSE(pack->category()); + + cat.addPackage(pack); + + REQUIRE(cat.packages().size() == 1); + REQUIRE(pack->category() == &cat); +} + +TEST_CASE("package type from string", M) { + SECTION("null") { + REQUIRE(Package::convertType(0) == Package::UnknownType); + } + + SECTION("unknown") { + REQUIRE(Package::convertType("yoyo") == Package::UnknownType); + } + + SECTION("script") { + REQUIRE(Package::convertType("script") == Package::ScriptType); + } +} diff --git a/test/database_v1.cpp b/test/database_v1.cpp @@ -17,3 +17,45 @@ TEST_CASE("unnamed category", M) { CHECK(db.get() == 0); REQUIRE(string(error) == "missing category name"); } + +TEST_CASE("empty category", M) { + const char *error = 0; + DatabasePtr db = Database::load(DBPATH "empty_category.xml", &error); + + REQUIRE(error == 0); + REQUIRE(db->categories().size() == 1); + REQUIRE(db->category(0)->name() == "Hello World"); + REQUIRE(db->category(0)->packages().empty()); +} + +TEST_CASE("invalid category tag", M) { + const char *error = ""; + DatabasePtr db = Database::load(DBPATH "wrong_category_tag.xml", &error); + + CHECK(db.get() == 0); + REQUIRE(string(error) == "not a category"); +} + +TEST_CASE("unnamed package", M) { + const char *error = ""; + DatabasePtr db = Database::load(DBPATH "unnamed_package.xml", &error); + + CHECK(db.get() == 0); + REQUIRE(string(error) == "missing package name"); +} + +TEST_CASE("invalid package type", M) { + const char *error = ""; + DatabasePtr db = Database::load(DBPATH "invalid_type.xml", &error); + + CHECK(db.get() == 0); + REQUIRE(string(error) == "unsupported package type"); +} + +TEST_CASE("anonymous package", M) { + const char *error = ""; + DatabasePtr db = Database::load(DBPATH "anonymous_package.xml", &error); + + CHECK(db.get() == 0); + REQUIRE(string(error) == "package is anonymous"); +} diff --git a/test/db/v1/anonymous_package.xml b/test/db/v1/anonymous_package.xml @@ -0,0 +1,6 @@ +<index version="1"> + <category name="test"> + <reapack name="abc" type="script" /> + <reapack name="abc" type="script" author="" /> + </category> +</index> diff --git a/test/db/v1/empty_category.xml b/test/db/v1/empty_category.xml @@ -0,0 +1,3 @@ +<index version="1"> + <category name="Hello World"/> +</index> diff --git a/test/db/v1/invalid_type.xml b/test/db/v1/invalid_type.xml @@ -0,0 +1,6 @@ +<index version="1"> + <category name="test"> + <reapack name="a" /> + <reapack name="c" type="yoyo" /> + </category> +</index> diff --git a/test/db/v1/unnamed_category.xml b/test/db/v1/unnamed_category.xml @@ -1,3 +1,4 @@ <index version="1"> <category /> + <category name="" /> </index> diff --git a/test/db/v1/unnamed_package.xml b/test/db/v1/unnamed_package.xml @@ -0,0 +1,6 @@ +<index version="1"> + <category name="test"> + <reapack /> + <reapack name="" /> + </category> +</index> diff --git a/test/db/v1/wrong_category_tag.xml b/test/db/v1/wrong_category_tag.xml @@ -0,0 +1,3 @@ +<index version="1"> + <hello_world /> +</index>