From 47c34477bab7461c7628a54059b29055495d85dc Mon Sep 17 00:00:00 2001 From: nshaheed Date: Wed, 17 Apr 2024 17:12:10 -0700 Subject: [PATCH] added version parse and parsing strings into versions --- CMakeLists.txt | 1 + src/package.cpp | 65 ++++++++++++++++++++++++++++++ src/package.h | 16 ++++++++ src/test/package_test.cpp | 85 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 src/test/package_test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fe744c9..6632968 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,6 +91,7 @@ add_executable(tests ${SOURCES} src/test/exec_test.cpp src/test/fetch_test.cpp + src/test/package_test.cpp src/test/package_list_test.cpp ) diff --git a/src/package.cpp b/src/package.cpp index 5466d3c..f0579e4 100644 --- a/src/package.cpp +++ b/src/package.cpp @@ -120,6 +120,71 @@ void from_json(const json& j, PackageVersion& p) { } optional Package::latest_version(string os) { + optional latest; + + for (PackageVersion ver : versions) { + if (ver.os != os) continue; + } return {}; } +// converts a string of the format "1.2.3" into a Version struct +Version parseVersionString(const std::string& versionStr) { + Version version; + + vector values; + + size_t pos = 0; + string token; + string delimiter = "."; + + /*****/ + size_t last = 0; + size_t next = 0; + while ((next = versionStr.find(delimiter, last)) != string::npos) { + token = versionStr.substr(last, next-last); + + int value = std::stoi(token); + values.push_back(value); + + last = next + 1; + } + + token = versionStr.substr(last, versionStr.size() - last); + int value = std::stoi(token); + values.push_back(value); + + if (values.size() != 3) { + throw std::invalid_argument("Invalid version string format"); + } + + version.major = values[0]; + version.minor = values[1]; + version.patch = values[2]; + + return version; +} + +bool operator==(const Version& lhs, const Version& rhs) { + return std::tie(lhs.major, lhs.minor, lhs.patch) == std::tie(rhs.major, rhs.minor, rhs.patch); +} + +bool operator!=(const Version& lhs, const Version& rhs) { + return std::tie(lhs.major, lhs.minor, lhs.patch) != std::tie(rhs.major, rhs.minor, rhs.patch); +} + +bool operator<(const Version& lhs, const Version& rhs) { + return std::tie(lhs.major, lhs.minor, lhs.patch) < std::tie(rhs.major, rhs.minor, rhs.patch); +} + +bool operator<=(const Version& lhs, const Version& rhs) { + return std::tie(lhs.major, lhs.minor, lhs.patch) <= std::tie(rhs.major, rhs.minor, rhs.patch); +} + +bool operator>(const Version& lhs, const Version& rhs) { + return std::tie(lhs.major, lhs.minor, lhs.patch) > std::tie(rhs.major, rhs.minor, rhs.patch); +} + +bool operator>=(const Version& lhs, const Version& rhs) { + return std::tie(lhs.major, lhs.minor, lhs.patch) >= std::tie(rhs.major, rhs.minor, rhs.patch); +} diff --git a/src/package.h b/src/package.h index dcccbdb..27020ec 100644 --- a/src/package.h +++ b/src/package.h @@ -59,4 +59,20 @@ struct Package { void to_json(json& j, const Package& p); void from_json(const json& j, Package& p); +struct Version { + int major; + int minor; + int patch; + + // Equality operator overload + friend bool operator==(const Version& lhs, const Version& rhs); + friend bool operator!=(const Version& lhs, const Version& rhs); + friend bool operator<(const Version& lhs, const Version& rhs); + friend bool operator<=(const Version& lhs, const Version& rhs); + friend bool operator>(const Version& lhs, const Version& rhs); + friend bool operator>=(const Version& lhs, const Version& rhs); +}; + +Version parseVersionString(const std::string& versionStr); + #endif diff --git a/src/test/package_test.cpp b/src/test/package_test.cpp new file mode 100644 index 0000000..76c1312 --- /dev/null +++ b/src/test/package_test.cpp @@ -0,0 +1,85 @@ +#include "package.h" +#include + +TEST_CASE("Parsing valid version string") { + SECTION("Valid version string") { + std::string versionStr = "1.2.3"; + Version expectedVersion{1, 2, 3}; + REQUIRE(parseVersionString(versionStr) == expectedVersion); + } + + SECTION("Version string with zero values") { + std::string versionStr = "0.0.0"; + Version expectedVersion{0, 0, 0}; + REQUIRE(parseVersionString(versionStr) == expectedVersion); + } + + SECTION("Version string with large values") { + std::string versionStr = "123456789.987654321.1234567890"; + Version expectedVersion{123456789, 987654321, 1234567890}; + REQUIRE(parseVersionString(versionStr) == expectedVersion); + } +} + +TEST_CASE("Parsing invalid version string") { + SECTION("Invalid format: Missing minor version") { + std::string versionStr = "1..3"; + REQUIRE_THROWS_AS(parseVersionString(versionStr), std::invalid_argument); + } + + SECTION("Invalid format: Extra dot") { + std::string versionStr = "1.2.3."; + REQUIRE_THROWS_AS(parseVersionString(versionStr), std::invalid_argument); + } + + SECTION("Invalid format: Non-numeric character") { + std::string versionStr = "1.2.x"; + REQUIRE_THROWS_AS(parseVersionString(versionStr), std::invalid_argument); + } + + SECTION("Invalid format: Empty string") { + std::string versionStr = ""; + REQUIRE_THROWS_AS(parseVersionString(versionStr), std::invalid_argument); + } +} + + +TEST_CASE("Comparison operators for Version struct") { + Version v1{1, 2, 3}; + Version v2{1, 2, 3}; + Version v3{1, 2, 4}; + + SECTION("Equality (==)") { + REQUIRE(v1 == v2); + REQUIRE_FALSE(v1 == v3); + } + + SECTION("Inequality (!=)") { + REQUIRE_FALSE(v1 != v2); + REQUIRE(v1 != v3); + } + + SECTION("Less than (<)") { + REQUIRE_FALSE(v1 < v2); + REQUIRE(v1 < v3); + REQUIRE_FALSE(v3 < v1); + } + + SECTION("Less than or equal to (<=)") { + REQUIRE(v1 <= v2); + REQUIRE(v1 <= v3); + REQUIRE_FALSE(v3 <= v1); + } + + SECTION("Greater than (>)") { + REQUIRE_FALSE(v1 > v2); + REQUIRE_FALSE(v1 > v3); + REQUIRE(v3 > v1); + } + + SECTION("Greater than or equal to (>=)") { + REQUIRE(v1 >= v2); + REQUIRE_FALSE(v1 >= v3); + REQUIRE(v3 >= v1); + } +}