commit 5a2a2cd165f7bbe8d995e7a787c0039c930eecc9
parent 9b0fe4248b2c92756de56152ed9aa1b1ff48ebe6
Author: cfillion <cfillion@users.noreply.github.com>
Date: Fri, 18 Dec 2015 19:51:16 -0500
ensure the package tree cannot be jumbled with another tree
Diffstat:
14 files changed, 182 insertions(+), 119 deletions(-)
diff --git a/src/database.cpp b/src/database.cpp
@@ -65,10 +65,12 @@ Database::~Database()
void Database::addCategory(Category *cat)
{
+ if(cat->database() != this)
+ throw reapack_error("category belongs to another database");
+
if(cat->packages().empty())
return;
- cat->setDatabase(this);
m_categories.push_back(cat);
m_packages.insert(m_packages.end(),
@@ -93,13 +95,15 @@ string Category::fullName() const
return m_database ? m_database->name() + "/" + m_name : m_name;
}
-void Category::addPackage(Package *pack)
+void Category::addPackage(Package *pkg)
{
- if(pack->type() == Package::UnknownType)
+ if(pkg->category() != this)
+ throw reapack_error("package belongs to another category");
+
+ if(pkg->type() == Package::UnknownType)
return; // silently discard unknown package types
- else if(pack->versions().empty())
+ else if(pkg->versions().empty())
return;
- pack->setCategory(this);
- m_packages.push_back(pack);
+ m_packages.push_back(pkg);
}
diff --git a/src/database.hpp b/src/database.hpp
@@ -60,12 +60,10 @@ public:
Category(const std::string &name, Database * = nullptr);
~Category();
+ Database *database() const { return m_database; }
const std::string &name() const { return m_name; }
std::string fullName() const;
- void setDatabase(Database *db) { m_database = db; }
- Database *database() const { return m_database; }
-
void addPackage(Package *pack);
const PackageList &packages() const { return m_packages; }
Package *package(const size_t i) const { return m_packages[i]; }
diff --git a/src/database_v1.cpp b/src/database_v1.cpp
@@ -114,7 +114,7 @@ void LoadVersionV1(TiXmlElement *verNode, Package *pkg)
const char *url = node->GetText();
if(!url) url = "";
- ver->addSource(new Source(Source::ConvertPlatform(platform), file, url));
+ ver->addSource(new Source(Source::ConvertPlatform(platform), file, url, ver));
node = node->NextSiblingElement("source");
}
diff --git a/src/package.cpp b/src/package.cpp
@@ -52,10 +52,12 @@ Package::~Package()
void Package::addVersion(Version *ver)
{
+ if(ver->package() != this)
+ throw reapack_error("version belongs to another package");
+
if(ver->sources().empty())
return;
- ver->setPackage(this);
m_versions.insert(ver);
}
diff --git a/src/package.hpp b/src/package.hpp
@@ -38,9 +38,7 @@ public:
Package(const Type, const std::string &name, Category * = nullptr);
~Package();
- void setCategory(Category *cat) { m_category = cat; }
Category *category() const { return m_category; }
-
Type type() const { return m_type; }
const std::string &name() const { return m_name; }
std::string fullName() const;
diff --git a/src/source.cpp b/src/source.cpp
@@ -43,8 +43,9 @@ Source::Platform Source::ConvertPlatform(const char *platform)
return UnknownPlatform;
}
-Source::Source(const Platform platform, const string &file, const string &url)
- : m_platform(platform), m_file(file), m_url(url), m_version(nullptr)
+Source::Source(const Platform platform, const string &file,
+ const string &url, Version *ver)
+ : m_platform(platform), m_file(file), m_url(url), m_version(ver)
{
if(m_url.empty())
throw reapack_error("empty source url");
diff --git a/src/source.hpp b/src/source.hpp
@@ -48,13 +48,13 @@ public:
static Platform ConvertPlatform(const char *);
- Source(const Platform, const std::string &file, const std::string &url);
+ Source(const Platform, const std::string &file,
+ const std::string &url, Version * = nullptr);
Platform platform() const { return m_platform; }
const std::string &file() const;
const std::string &url() const { return m_url; }
- void setVersion(Version *ver) { m_version = ver; }
Version *version() const { return m_version; }
Package *package() const;
diff --git a/src/version.cpp b/src/version.cpp
@@ -93,7 +93,8 @@ void Version::addSource(Source *source)
#endif
#endif
- source->setVersion(this);
+ if(source->version() != this)
+ throw reapack_error("source belongs to another version");
const Path path = source->targetPath();
m_files.insert(path);
diff --git a/src/version.hpp b/src/version.hpp
@@ -36,9 +36,7 @@ public:
std::string fullName() const;
uint64_t code() const { return m_code; }
- void setPackage(Package *pkg) { m_package = pkg; }
Package *package() const { return m_package; }
-
void setChangelog(const std::string &);
const std::string &changelog() const { return m_changelog; }
diff --git a/test/database.cpp b/test/database.cpp
@@ -81,8 +81,8 @@ TEST_CASE("add category", M) {
Database db("a");
Category *cat = new Category("a", &db);
Package *pack = new Package(Package::ScriptType, "name", cat);
- Source *source = new Source(Source::GenericPlatform, string(), "google.com");
Version *ver = new Version("1", pack);
+ Source *source = new Source(Source::GenericPlatform, {}, "google.com", ver);
ver->addSource(source);
pack->addVersion(ver);
@@ -96,49 +96,77 @@ TEST_CASE("add category", M) {
REQUIRE(db.packages() == cat->packages());
}
+TEST_CASE("add owned category", M) {
+ Database db1("a");
+ Database db2("b");
+
+ Category *cat = new Category("name", &db1);
+
+ try {
+ db2.addCategory(cat);
+ FAIL();
+ }
+ catch(const reapack_error &e) {
+ delete cat;
+ REQUIRE(string(e.what()) == "category belongs to another database");
+ }
+}
+
TEST_CASE("drop empty category", M) {
Database db("a");
- db.addCategory(new Category("a"));
+ db.addCategory(new Category("a", &db));
REQUIRE(db.categories().empty());
}
TEST_CASE("add a package", M) {
Database db("a");
- Category cat1("a", &db);
- Package *pack = new Package(Package::ScriptType, "name", &cat1);
+ Category cat("a", &db);
+ Package *pack = new Package(Package::ScriptType, "name", &cat);
Version *ver = new Version("1", pack);
- ver->addSource(new Source(Source::GenericPlatform, string(), "google.com"));
+ ver->addSource(new Source(Source::GenericPlatform, {}, "google.com", ver));
pack->addVersion(ver);
- CHECK(pack->category() == &cat1);
+ CHECK(cat.packages().size() == 0);
- Category cat2("b");
- CHECK(cat2.packages().size() == 0);
+ cat.addPackage(pack);
- cat2.addPackage(pack);
+ REQUIRE(cat.packages().size() == 1);
+ REQUIRE(pack->category() == &cat);
+}
- REQUIRE(cat2.packages().size() == 1);
- REQUIRE(pack->category() == &cat2);
+TEST_CASE("add owned package", M) {
+ Category cat1("a");
+ Package *pack = new Package(Package::ScriptType, "name", &cat1);
+
+ try {
+ Category cat2("b");
+ cat2.addPackage(pack);
+ FAIL();
+ }
+ catch(const reapack_error &e) {
+ delete pack;
+ REQUIRE(string(e.what()) == "package belongs to another category");
+ }
}
TEST_CASE("drop empty package", M) {
Category cat("a");
- cat.addPackage(new Package(Package::ScriptType, "name"));
+ cat.addPackage(new Package(Package::ScriptType, "name", &cat));
REQUIRE(cat.packages().empty());
}
TEST_CASE("drop unknown package", M) {
Category cat("a");
- cat.addPackage(new Package(Package::UnknownType, "name"));
+ cat.addPackage(new Package(Package::UnknownType, "name", &cat));
REQUIRE(cat.packages().size() == 0);
}
TEST_CASE("empty category name", M) {
try {
- Category cat{string()};
+ Category cat{string(), nullptr};
FAIL();
}
catch(const reapack_error &e) {
@@ -147,10 +175,10 @@ TEST_CASE("empty category name", M) {
}
TEST_CASE("category full name", M) {
- Category cat("Category Name");
- REQUIRE(cat.fullName() == "Category Name");
+ Category cat1("Category Name");
+ REQUIRE(cat1.fullName() == "Category Name");
Database db("Database Name");
- cat.setDatabase(&db);
- REQUIRE(cat.fullName() == "Database Name/Category Name");
+ Category cat2("Category Name", &db);
+ REQUIRE(cat2.fullName() == "Database Name/Category Name");
}
diff --git a/test/package.cpp b/test/package.cpp
@@ -39,14 +39,11 @@ TEST_CASE("package versions are sorted", M) {
Package pack(Package::ScriptType, "a", &cat);
CHECK(pack.versions().size() == 0);
- Source *sourceA = new Source(Source::GenericPlatform, string(), "google.com");
- Source *sourceB = new Source(Source::GenericPlatform, string(), "google.com");
-
Version *final = new Version("1", &pack);
- final->addSource(sourceA);
+ final->addSource(new Source(Source::GenericPlatform, {}, "google.com", final));
Version *alpha = new Version("0.1", &pack);
- alpha->addSource(sourceB);
+ alpha->addSource(new Source(Source::GenericPlatform, {}, "google.com", alpha));
pack.addVersion(final);
REQUIRE(final->package() == &pack);
@@ -62,19 +59,33 @@ TEST_CASE("package versions are sorted", M) {
TEST_CASE("drop empty version", M) {
Package pack(Package::ScriptType, "a");
- pack.addVersion(new Version("1"));
+ pack.addVersion(new Version("1", &pack));
REQUIRE(pack.versions().empty());
REQUIRE(pack.lastVersion() == nullptr);
}
+TEST_CASE("add owned version", M) {
+ Package pack1(Package::ScriptType, "a");
+ Package pack2(Package::ScriptType, "a");
+
+ Version *ver = new Version("1", &pack1);
+
+ try {
+ pack2.addVersion(ver);
+ FAIL();
+ }
+ catch(const reapack_error &e) {
+ delete ver;
+ REQUIRE(string(e.what()) == "version belongs to another package");
+ }
+}
+
TEST_CASE("unknown target path", M) {
Database db("name");
- Category cat("name");
- cat.setDatabase(&db);
+ Category cat("name", &db);
- Package pack(Package::UnknownType, "a");
- pack.setCategory(&cat);
+ Package pack(Package::UnknownType, "a", &cat);
try {
pack.targetPath();
@@ -87,12 +98,9 @@ TEST_CASE("unknown target path", M) {
TEST_CASE("script target path", M) {
Database db("Database Name");
+ Category cat("Category Name", &db);
- Category cat("Category Name");
- cat.setDatabase(&db);
-
- Package pack(Package::ScriptType, "file.name");
- pack.setCategory(&cat);
+ Package pack(Package::ScriptType, "file.name", &cat);
Path expected;
expected.append("Scripts");
@@ -115,16 +123,22 @@ TEST_CASE("script target path without category", M) {
}
TEST_CASE("full name", M) {
- Database db("Database Name");
-
- Category cat("Category Name");
+ SECTION("no category") {
+ Package pack(Package::ScriptType, "file.name");
+ REQUIRE(pack.fullName() == "file.name");
+ }
- Package pack(Package::ScriptType, "file.name");
- REQUIRE(pack.fullName() == "file.name");
+ SECTION("with category") {
+ Category cat("Category Name");
+ Package pack(Package::ScriptType, "file.name", &cat);
+ REQUIRE(pack.fullName() == "Category Name/file.name");
+ }
- pack.setCategory(&cat);
- REQUIRE(pack.fullName() == "Category Name/file.name");
+ SECTION("with database") {
+ Database db("Database Name");
+ Category cat("Category Name", &db);
+ Package pack(Package::ScriptType, "file.name", &cat);
- cat.setDatabase(&db);
- REQUIRE(pack.fullName() == "Database Name/Category Name/file.name");
+ REQUIRE(pack.fullName() == "Database Name/Category Name/file.name");
+ }
}
diff --git a/test/registry.cpp b/test/registry.cpp
@@ -10,11 +10,10 @@ static const char *M = "[registry]";
#define MAKE_PACKAGE \
Database db("Hello"); \
- Category cat("Hello"); \
- cat.setDatabase(&db); \
+ Category cat("Hello", &db); \
Package pkg(Package::ScriptType, "Hello", &cat); \
Version *ver = new Version("1.0", &pkg); \
- Source *src = new Source(Source::GenericPlatform, "file", "url"); \
+ Source *src = new Source(Source::GenericPlatform, "file", "url", ver); \
ver->addSource(src); \
pkg.addVersion(ver);
@@ -42,9 +41,8 @@ TEST_CASE("query up to date pacakge", M) {
TEST_CASE("bump version", M) {
MAKE_PACKAGE
- Version *ver2 = new Version("2.0");
- ver2->setPackage(&pkg);
- ver2->addSource(new Source(Source::GenericPlatform, "file", "url"));
+ Version *ver2 = new Version("2.0", &pkg);
+ ver2->addSource(new Source(Source::GenericPlatform, "file", "url", ver2));
Registry reg;
reg.push(&pkg);
diff --git a/test/source.cpp b/test/source.cpp
@@ -87,16 +87,14 @@ TEST_CASE("full name without version", M) {
TEST_CASE("full name with version", M) {
SECTION("with source name") {
Version ver("1.0");
- Source source(Source::UnknownPlatform, "a", "b");
- source.setVersion(&ver);
+ Source source(Source::UnknownPlatform, "a", "b", &ver);
REQUIRE(source.fullName() == "v1.0 (a)");
}
SECTION("with source name") {
Version ver("1.0");
- Source source(Source::UnknownPlatform, string(), "b");
- source.setVersion(&ver);
+ Source source(Source::UnknownPlatform, string(), "b", &ver);
REQUIRE(source.fullName() == ver.fullName());
}
@@ -104,18 +102,11 @@ TEST_CASE("full name with version", M) {
TEST_CASE("source target path", M) {
Database db("Database Name");
+ Category cat("Category Name", &db);
+ Package pack(Package::ScriptType, "package name", &cat);
+ Version ver("1.0", &pack);
- Category cat("Category Name");
- cat.setDatabase(&db);
-
- Package pack(Package::ScriptType, "package name");
- pack.setCategory(&cat);
-
- Version ver("1.0");
- ver.setPackage(&pack);
-
- Source source(Source::GenericPlatform, "file.name", "https://google.com");
- source.setVersion(&ver);
+ Source source(Source::GenericPlatform, "file.name", "url", &ver);
Path expected;
expected.append("Scripts");
diff --git a/test/version.cpp b/test/version.cpp
@@ -84,20 +84,34 @@ TEST_CASE("version with 5 components", M) {
}
TEST_CASE("version full name", M) {
- Version ver("1.0");
- REQUIRE(ver.fullName() == "v1.0");
+ SECTION("no package") {
+ Version ver("1.0");
+ REQUIRE(ver.fullName() == "v1.0");
+ }
+
+ SECTION("with package") {
+ Package pkg(Package::UnknownType, "file.name");
+ Version ver("1.0", &pkg);
- Package pkg(Package::UnknownType, "file.name");
- ver.setPackage(&pkg);
- REQUIRE(ver.fullName() == "file.name v1.0");
+ REQUIRE(ver.fullName() == "file.name v1.0");
+ }
- Category cat("Category Name");
- pkg.setCategory(&cat);
- REQUIRE(ver.fullName() == "Category Name/file.name v1.0");
+ SECTION("with category") {
+ Category cat("Category Name");
+ Package pkg(Package::UnknownType, "file.name", &cat);
+ Version ver("1.0", &pkg);
+
+ REQUIRE(ver.fullName() == "Category Name/file.name v1.0");
+ }
- Database db("Database Name");
- cat.setDatabase(&db);
- REQUIRE(ver.fullName() == "Database Name/Category Name/file.name v1.0");
+ SECTION("with database") {
+ Database db("Database Name");
+ Category cat("Category Name", &db);
+ Package pkg(Package::UnknownType, "file.name", &cat);
+ Version ver("1.0", &pkg);
+
+ REQUIRE(ver.fullName() == "Database Name/Category Name/file.name v1.0");
+ }
}
TEST_CASE("add source", M) {
@@ -105,7 +119,7 @@ TEST_CASE("add source", M) {
CHECK(ver.sources().size() == 0);
- Source *src = new Source(Source::GenericPlatform, "a", "b");
+ Source *src = new Source(Source::GenericPlatform, "a", "b", &ver);
ver.addSource(src);
CHECK(ver.sources().size() == 1);
@@ -114,10 +128,26 @@ TEST_CASE("add source", M) {
REQUIRE(ver.source(0) == src);
}
+TEST_CASE("add owned source", M) {
+ MAKE_VERSION
+
+ Version ver2("1");
+ Source *src = new Source(Source::GenericPlatform, "a", "b", &ver2);
+
+ try {
+ ver.addSource(src);
+ FAIL();
+ }
+ catch(const reapack_error &e) {
+ delete src;
+ REQUIRE(string(e.what()) == "source belongs to another version");
+ }
+}
+
TEST_CASE("list files", M) {
MAKE_VERSION
- Source *src1 = new Source(Source::GenericPlatform, "file", "url");
+ Source *src1 = new Source(Source::GenericPlatform, "file", "url", &ver);
ver.addSource(src1);
Path path1;
@@ -132,7 +162,7 @@ TEST_CASE("list files", M) {
TEST_CASE("drop sources for unknown platforms", M) {
MAKE_VERSION
- ver.addSource(new Source(Source::UnknownPlatform, "a", "b"));
+ ver.addSource(new Source(Source::UnknownPlatform, "a", "b", &ver));
REQUIRE(ver.sources().size() == 0);
}
@@ -141,9 +171,9 @@ TEST_CASE("drop sources for unknown platforms", M) {
TEST_CASE("drop windows sources on os x", M) {
MAKE_VERSION
- ver.addSource(new Source(Source::WindowsPlatform, "a", "b"));
- ver.addSource(new Source(Source::Win32Platform, "a", "b"));
- ver.addSource(new Source(Source::Win64Platform, "a", "b"));
+ ver.addSource(new Source(Source::WindowsPlatform, "a", "b", &ver));
+ ver.addSource(new Source(Source::Win32Platform, "a", "b", &ver));
+ ver.addSource(new Source(Source::Win64Platform, "a", "b", &ver));
REQUIRE(ver.sources().size() == 0);
}
@@ -151,7 +181,7 @@ TEST_CASE("drop windows sources on os x", M) {
#ifdef __x86_64__
TEST_CASE("drop 32-bit sources on os x 64-bit", M) {
MAKE_VERSION
- ver.addSource(new Source(Source::Darwin32Platform, "a", "b"));
+ ver.addSource(new Source(Source::Darwin32Platform, "a", "b", &ver));
REQUIRE(ver.sources().size() == 0);
}
@@ -159,16 +189,16 @@ TEST_CASE("drop 32-bit sources on os x 64-bit", M) {
TEST_CASE("valid sources for os x 64-bit", M) {
MAKE_VERSION
- ver.addSource(new Source(Source::GenericPlatform, "a", "b"));
- ver.addSource(new Source(Source::DarwinPlatform, "a", "b"));
- ver.addSource(new Source(Source::Darwin64Platform, "a", "b"));
+ ver.addSource(new Source(Source::GenericPlatform, "a", "b", &ver));
+ ver.addSource(new Source(Source::DarwinPlatform, "a", "b", &ver));
+ ver.addSource(new Source(Source::Darwin64Platform, "a", "b", &ver));
REQUIRE(ver.sources().size() == 3);
}
#else
TEST_CASE("drop 64-bit sources on os x 32-bit", M) {
MAKE_VERSION
- ver.addSource(new Source(Source::Darwin64Platform, "a", "b"));
+ ver.addSource(new Source(Source::Darwin64Platform, "a", "b", &ver));
REQUIRE(ver.sources().size() == 0);
}
@@ -176,9 +206,9 @@ TEST_CASE("drop 64-bit sources on os x 32-bit", M) {
TEST_CASE("valid sources for os x 32-bit", M) {
MAKE_VERSION
- ver.addSource(new Source(Source::GenericPlatform, "a", "b"));
- ver.addSource(new Source(Source::DarwinPlatform, "a", "b"));
- ver.addSource(new Source(Source::Darwin32Platform, "a", "b"));
+ ver.addSource(new Source(Source::GenericPlatform, "a", "b", &ver));
+ ver.addSource(new Source(Source::DarwinPlatform, "a", "b", &ver));
+ ver.addSource(new Source(Source::Darwin32Platform, "a", "b", &ver));
REQUIRE(ver.sources().size() == 3);
}
@@ -188,9 +218,9 @@ TEST_CASE("valid sources for os x 32-bit", M) {
TEST_CASE("drop os x sources on windows", M) {
MAKE_VERSION
- ver.addSource(new Source(Source::DarwinPlatform, "a", "b"));
- ver.addSource(new Source(Source::Darwin32Platform, "a", "b"));
- ver.addSource(new Source(Source::Darwin64Platform, "a", "b"));
+ ver.addSource(new Source(Source::DarwinPlatform, "a", "b", &ver));
+ ver.addSource(new Source(Source::Darwin32Platform, "a", "b", &ver));
+ ver.addSource(new Source(Source::Darwin64Platform, "a", "b", &ver));
REQUIRE(ver.sources().size() == 0);
}
@@ -198,7 +228,7 @@ TEST_CASE("drop os x sources on windows", M) {
#ifdef _WIN64
TEST_CASE("drop 32-bit sources on windows 64-bit", M) {
MAKE_VERSION
- ver.addSource(new Source(Source::Win32Platform, "a", "b"));
+ ver.addSource(new Source(Source::Win32Platform, "a", "b", &ver));
REQUIRE(ver.sources().size() == 0);
}
@@ -206,16 +236,16 @@ TEST_CASE("drop 32-bit sources on windows 64-bit", M) {
TEST_CASE("valid sources for windows 64-bit", M) {
MAKE_VERSION
- ver.addSource(new Source(Source::GenericPlatform, "a", "b"));
- ver.addSource(new Source(Source::WindowsPlatform, "a", "b"));
- ver.addSource(new Source(Source::Win64Platform, "a", "b"));
+ ver.addSource(new Source(Source::GenericPlatform, "a", "b", &ver));
+ ver.addSource(new Source(Source::WindowsPlatform, "a", "b", &ver));
+ ver.addSource(new Source(Source::Win64Platform, "a", "b", &ver));
REQUIRE(ver.sources().size() == 3);
}
#else
TEST_CASE("drop 64-bit sources on windows 32-bit", M) {
MAKE_VERSION
- ver.addSource(new Source(Source::Win64Platform, "a", "b"));
+ ver.addSource(new Source(Source::Win64Platform, "a", "b", &ver));
REQUIRE(ver.sources().size() == 0);
}
@@ -223,9 +253,9 @@ TEST_CASE("drop 64-bit sources on windows 32-bit", M) {
TEST_CASE("valid sources for windows 32-bit", M) {
MAKE_VERSION
- ver.addSource(new Source(Source::GenericPlatform, "a", "b"));
- ver.addSource(new Source(Source::WindowsPlatform, "a", "b"));
- ver.addSource(new Source(Source::Win32Platform, "a", "b"));
+ ver.addSource(new Source(Source::GenericPlatform, "a", "b", &ver));
+ ver.addSource(new Source(Source::WindowsPlatform, "a", "b", &ver));
+ ver.addSource(new Source(Source::Win32Platform, "a", "b", &ver));
REQUIRE(ver.sources().size() == 3);
}