Outsource version comparison algorithm.

The version comparison algorithm has been split into its own library,
Pseudosem.
This commit is contained in:
Oliver Hamlet
2015-08-24 16:56:04 +01:00
parent 143388e287
commit 1a45c948bb
10 changed files with 47 additions and 517 deletions
+6 -1
View File
@@ -64,6 +64,10 @@ IF (NOT DEFINED CEF_ROOT)
set (CEF_ROOT "../../cef")
ENDIF ()
IF (NOT DEFINED PSEUDOSEM_ROOT)
set (PSEUDOSEM_ROOT "../../pseudosem")
ENDIF ()
set (Boost_USE_STATIC_LIBS ${PROJECT_STATIC_RUNTIME})
set (Boost_USE_MULTITHREADED ON)
set (Boost_USE_STATIC_RUNTIME ${PROJECT_STATIC_RUNTIME})
@@ -196,7 +200,8 @@ include_directories ("${CMAKE_SOURCE_DIR}/src"
${LIBESPM_ROOT}
${Boost_INCLUDE_DIRS}
${YAML_CPP_INCLUDE_DIR}
${GTEST_INCLUDE_DIRS})
${GTEST_INCLUDE_DIRS}
"${PSEUDOSEM_ROOT}/include")
link_directories ("${LIBLOADORDER_ROOT}/build"
"${LIBGIT2_ROOT}/build"
+2 -1
View File
@@ -24,9 +24,10 @@ LOOT uses [CMake](http://cmake.org) to generate build files, and requires the fo
* [Libespm](http://github.com/WrinklyNinja/libespm)
* [Libgit2](http://libgit2.github.com/) v0.23.1
* [Libloadorder](http://github.com/WrinklyNinja/libloadorder)
* [Pseudosem](http://github.com/WrinklyNinja/pseudosem): v1.0.0
* [yaml-cpp](http://github.com/WrinklyNinja/yaml-cpp): Use the `patched-for-loot` branch.
Libespm does not require any additional setup. The rest of the libraries must be built separately. Instructions for building them and LOOT itself using Microsoft Visual Studio are given in [docs/BUILD.MSVC.md](docs/BUILD.MSVC.md).
Libespm and Pseudosem do not require any additional setup. The rest of the libraries must be built separately. Instructions for building them and LOOT itself using Microsoft Visual Studio are given in [docs/BUILD.MSVC.md](docs/BUILD.MSVC.md).
Although LOOT uses a cross-platform build system and cross-platform libraries, it does rely on some Windows API functionality. Anyone wishing to port LOOT to other platforms will need to ensure equivalent functionality is implemented for their target platform. The Windows API code is wrapped in `#ifdef _WIN32` blocks so that it can be easily identified.
+1
View File
@@ -69,6 +69,7 @@ Parameter | Values | Default |Description
`LIBESPM_ROOT` | path | `../../libespm` | Path to the root of the libespm repository folder.
`LIBGIT2_ROOT` | path | `../../libgit2` | Path to the root of the libgit2 repository folder.
`LIBLOADORDER_ROOT` | path | `../../libloadorder` | Path to the root of the libloadorder repository folder.
`PSEUDOSEM_ROOT` | Path | `../../pseudosem` | Path to the root of the Pseudosem repository folder.
The default paths given in the table above are relative to LOOT's `CMakeLists.txt`.
+2 -1
View File
@@ -513,7 +513,8 @@ var {
<a href="https://github.com/libgit2/libgit2">libgit2</a>,
<a href="https://github.com/WrinklyNinja/libloadorder">libloadorder</a>,
<a href="https://github.com/chjj/marked">Marked</a>,
<a href="https://www.polymer-project.org/">Polymer</a>
<a href="https://github.com/WrinklyNinja/pseudosem">pseudosem</a>,
<a href="https://www.polymer-project.org/">Polymer</a>,
<a href="http://requirejs.org">RequireJS</a> and
<a href="https://github.com/WrinklyNinja/yaml-cpp">yaml-cpp</a> libraries, and the <a href="https://bitbucket.org/chromiumembedded/cef">Chromium Embedded Framework</a>. Copyright license information for all these may be found <a href="licenses/Licenses.txt">here</a>.
+1
View File
@@ -10,6 +10,7 @@ LOOT uses a number of libraries, and their licenses are listed in this file.
* Libgit2 - GNU GPL v2; see "GNU GPL v2 (libgit2).txt" for the text.
* Libloadorder - GNU GPL v3; see "GNU GPL v3.txt" for the text.
* Marked - MIT License; see "MIT License (Marked).txt" for the text.
* Pseudosem - MIT License; see "MIT License (Pseudosem).txt" for the text.
* Polymer - BSD license; see "BSD License (Polymer).txt" for the text.
* RequireJS - MIT License; see "MIT License (RequireJS).txt" for the text.
* yaml-cpp - MIT License; see "MIT License (yaml-cpp).txt" for the text.
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Oliver Hamlet
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+4
View File
@@ -34,3 +34,7 @@ mkdir libloadorder/build && cd libloadorder/build
cmake .. -DPROJECT_ARCH=64 -DPROJECT_STATIC_RUNTIME=OFF -DBUILD_SHARED_LIBS=OFF -DGTEST_ROOT=../gtest-1.7.0
make loadorder64
cd ../..
# Install pseudosem
wget https://github.com/WrinklyNinja/pseudosem/archive/1.0.0.tar.gz -O - | tar -xz
mv pseudosem-1.0.0 pseudosem
+2 -1
View File
@@ -54,7 +54,8 @@
* [Boost](http://www.boost.org/),
* [libespm](http://github.com/WrinklyNinja/libespm),
* [libgit2](http://github.com/libgit2/libgit2),
* [libloadorder](http://github.com/WrinklyNinja/libloadorder/) and
* [libloadorder](http://github.com/WrinklyNinja/libloadorder/),
* [Pseudosem](http://github.com/WrinklyNinja/pseudosem) and
* [yaml-cpp](http://github.com/WrinklyNinja/yaml-cpp) libraries. Copyright
* license information for all these may be found in the
* "docs/licenses/Licenses.txt" file.
+8 -157
View File
@@ -25,13 +25,7 @@
#include "helpers.h"
#include "version.h"
#include <boost/algorithm/string.hpp>
#include <algorithm>
#include <regex>
#include <sstream>
#include <iostream>
#include <pseudosem.h>
#ifdef _WIN32
# ifndef UNICODE
@@ -100,170 +94,27 @@ namespace loot {
return verString;
}
void Version::Decompose(std::vector<unsigned long>& release,
std::vector<std::string>& preRelease) const {
if (verString.empty())
return;
release.clear();
preRelease.clear();
// Find first '+' and trim to it.
string version(verString.substr(0, verString.find('+')));
// Split release string.
size_t pos = version.find_first_of(" :_-");
string relStr(version.substr(0, pos));
boost::trim_if(relStr, boost::is_any_of("."));
// Split release portion of version into what should be digit strings.
vector<string> temp;
boost::split(temp,
relStr,
boost::is_any_of("."),
boost::token_compress_on);
if (!temp.empty()) {
// Function to test if string does not contains only digits.
auto notDigits = [](const std::string& str) {
return !std::all_of(str.begin(), str.end(), ::isdigit);
};
// Unary string to unsigned long converter.
auto toul = [](const std::string& str) {
return stoul(str);
};
auto firstNonInt = find_if(temp.begin(), temp.end(), notDigits);
transform(temp.begin(),
firstNonInt,
back_inserter(release),
toul);
if (firstNonInt != temp.end())
preRelease.assign(firstNonInt, temp.end());
}
// Now split the pre-release portion of the version string.
if (pos != string::npos) {
string preRelStr(version.substr(pos));
boost::trim_if(preRelStr, boost::is_any_of(". :_-"));
boost::split(temp,
preRelStr,
boost::is_any_of(". :_-"),
boost::token_compress_on);
preRelease.insert(preRelease.end(), temp.begin(), temp.end());
}
}
bool Version::operator < (const Version& ver) const {
/* Version strings have a wide variety of possible formats.
The precedence rules set out by Semantic Versioning <http://semver.org>
are sufficient for comparisons, with the following extensions:
1. Strings must be lowercased before comparison.
2. Spaces (" "), colons (":") and underscores ("_") should be treated as
separator characters between prerelease version identifiers.
3. Version integers should be allowed to contain leading zeroes.
4. An arbitrary number of version integers should be supported.
5. If two strings contain a different number of version integers,
their version integers should be padded (preceding any pre-release
version or metadata) to equal length before comparison.
These extensions are to ensure that executable versions and plugin
versions are well-supported.
*/
vector<unsigned long> v1Release, v2Release;
vector<string> v1PreRelease, v2PreRelease;
this->Decompose(v1Release, v1PreRelease);
ver.Decompose(v2Release, v2PreRelease);
// Compare lengths of release vectors, and pad shorter with zeroes.
if (v1Release.size() < v2Release.size())
v1Release.resize(v2Release.size(), 0);
else if (v2Release.size() < v1Release.size())
v2Release.resize(v1Release.size(), 0);
// Now compare release numbers one by one.
for (size_t i = 0; i < v1Release.size(); ++i) {
if (v1Release[i] < v2Release[i])
return true;
if (v2Release[i] < v1Release[i])
return false;
}
// Release numbers are the same. Check pre-release strings. If one has
// pre-release strings while the other does not, the first is less.
if (v1PreRelease.empty() != v2PreRelease.empty())
return !v1PreRelease.empty();
if (v1PreRelease.empty())
return false;
auto isDigits = [](const std::string& str) {
return std::all_of(str.begin(), str.end(), ::isdigit);
};
// Compare pre-release strings one by one.
size_t i = 0;
while (i < v1PreRelease.size() && i < v2PreRelease.size()) {
bool v1IsInt = isDigits(v1PreRelease[i]);
bool v2IsInt = isDigits(v2PreRelease[i]);
// Integers have lower precedence than non-integer strings.
if (v1IsInt != v2IsInt)
return v1IsInt;
if (v1IsInt) {
// Compare integer values.
unsigned long v1Int = stoul(v1PreRelease[i]);
unsigned long v2Int = stoul(v2PreRelease[i]);
if (v1Int < v2Int)
return true;
if (v2Int < v1Int)
return false;
}
else {
// Compare string values.
if (v1PreRelease[i] < v2PreRelease[i])
return true;
if (v2PreRelease[i] < v1PreRelease[i])
return false;
}
++i;
}
// Have reached the end of one or both pre-release string vectors.
// If only the end of one was reached, it is less.
if (v1PreRelease.size() == v2PreRelease.size())
return false;
return i == v1PreRelease.size();
return pseudosem::compare(this->verString, ver.AsString()) < 0;
}
bool Version::operator > (const Version& ver) const {
return ver < *this;
return pseudosem::compare(this->verString, ver.AsString()) > 0;
}
bool Version::operator >= (const Version& ver) const {
return ver < *this || !(*this < ver);
return pseudosem::compare(this->verString, ver.AsString()) >= 0;
}
bool Version::operator <= (const Version& ver) const {
return *this < ver || !(ver < *this);
return pseudosem::compare(this->verString, ver.AsString()) <= 0;
}
bool Version::operator == (const Version& ver) const {
return !(*this < ver) && !(ver < *this);
return pseudosem::compare(this->verString, ver.AsString()) == 0;
}
bool Version::operator != (const Version& ver) const {
return *this < ver || ver < *this;
return pseudosem::compare(this->verString, ver.AsString()) != 0;
}
}
}
-356
View File
@@ -146,360 +146,4 @@ TEST_F(Version, NotEqual) {
EXPECT_TRUE(version2 != version1);
}
TEST_F(Version, SemVer_Patch) {
loot::Version version1, version2;
version1 = loot::Version(std::string("0.0.1"));
version2 = loot::Version(std::string("0.0.1"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
version1 = loot::Version(std::string("0.0.1"));
version2 = loot::Version(std::string("0.0.2"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.0.2"));
version2 = loot::Version(std::string("0.0.10"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
}
TEST_F(Version, SemVer_Minor) {
loot::Version version1, version2;
version1 = loot::Version(std::string("0.0.2"));
version2 = loot::Version(std::string("0.1.0"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.1.0"));
version2 = loot::Version(std::string("0.1.0"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
version1 = loot::Version(std::string("0.1.0"));
version2 = loot::Version(std::string("0.2.0"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.2.0"));
version2 = loot::Version(std::string("0.10.0"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
}
TEST_F(Version, SemVer_Major) {
loot::Version version1, version2;
version1 = loot::Version(std::string("0.2.0"));
version2 = loot::Version(std::string("1.0.0"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("1.0.0"));
version2 = loot::Version(std::string("1.0.0"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
version1 = loot::Version(std::string("0.1.0"));
version2 = loot::Version(std::string("0.2.0"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.2.0"));
version2 = loot::Version(std::string("0.10.0"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
}
TEST_F(Version, SemVer_PreRelease) {
loot::Version version1, version2;
version1 = loot::Version(std::string("0.0.1-1"));
version2 = loot::Version(std::string("0.0.1-1.alpha"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.0.1-1.alpha"));
version2 = loot::Version(std::string("0.0.1-2"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.0.1-2"));
version2 = loot::Version(std::string("0.0.1-alpha"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.0.1-alpha"));
version2 = loot::Version(std::string("0.0.1-alpha.1"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.0.1-alpha.1"));
version2 = loot::Version(std::string("0.0.1-alpha.beta"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.0.1-alpha.beta"));
version2 = loot::Version(std::string("0.0.1-beta"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.0.1-beta.2"));
version2 = loot::Version(std::string("0.0.1-beta.11"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.0.1-rc.1"));
version2 = loot::Version(std::string("0.0.1"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.0.0-alpha"));
version2 = loot::Version(std::string("0.0.1"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
}
TEST_F(Version, SemVer_Metadata) {
// Metadata should be ignored.
loot::Version version1, version2;
version1 = loot::Version(std::string("0.0.1+alpha"));
version2 = loot::Version(std::string("0.0.1+beta"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
version1 = loot::Version(std::string("0.0.1+alpha"));
version2 = loot::Version(std::string("0.0.1+1"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
version1 = loot::Version(std::string("0.0.1+1"));
version2 = loot::Version(std::string("0.0.1+2"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
}
TEST_F(Version, SemVer_Extension_LeadingZeroes) {
loot::Version version1, version2;
version1 = loot::Version(std::string("0.0.1-01"));
version2 = loot::Version(std::string("0.0.1-1"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
version1 = loot::Version(std::string("0.0.1-01"));
version2 = loot::Version(std::string("0.0.1-02"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.0.1-02"));
version2 = loot::Version(std::string("0.0.1-010"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.0.01"));
version2 = loot::Version(std::string("0.0.1"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
version1 = loot::Version(std::string("0.0.01"));
version2 = loot::Version(std::string("0.0.02"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.0.02"));
version2 = loot::Version(std::string("0.0.010"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.01.0"));
version2 = loot::Version(std::string("0.1.0"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
version1 = loot::Version(std::string("0.01.0"));
version2 = loot::Version(std::string("0.02.0"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.02.0"));
version2 = loot::Version(std::string("0.010.0"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("01.0.0"));
version2 = loot::Version(std::string("1.0.0"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
version1 = loot::Version(std::string("01.0.0"));
version2 = loot::Version(std::string("02.0.0"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("02.0.0"));
version2 = loot::Version(std::string("010.0.0"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
}
TEST_F(Version, SemVer_Extension_ArbitraryPeriods) {
loot::Version version1, version2;
version1 = loot::Version(std::string("1.0.0.0.0.0"));
version2 = loot::Version(std::string("1.0.0.0.0.1"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("1.0.0.01.0.0"));
version2 = loot::Version(std::string("1.0.0.1.0.0"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
}
TEST_F(Version, SemVer_Extension_Padding) {
loot::Version version1, version2;
version1 = loot::Version(std::string("1.0.0.0.0"));
version2 = loot::Version(std::string("1"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
version1 = loot::Version(std::string("0.1.0.0-beta"));
version2 = loot::Version(std::string("0.1-beta"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
version1 = loot::Version(std::string("0.1.0.0-alpha"));
version2 = loot::Version(std::string("0.1-beta"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.1-alpha"));
version2 = loot::Version(std::string("0.1.0.0-beta"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
version1 = loot::Version(std::string("0.0.0.1.0.0"));
version2 = loot::Version(std::string("0.0.0.1"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
version1 = loot::Version(std::string("1.0.0.0.0.0"));
version2 = loot::Version(std::string("1.0.0.1"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
}
TEST_F(Version, SemVer_Extension_Separators) {
loot::Version version1, version2;
version1 = loot::Version(std::string("1.0.0-alpha.1.2.3"));
version2 = loot::Version(std::string("1.0.0 alpha:1-2_3"));
EXPECT_FALSE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_TRUE(version1 == version2);
EXPECT_TRUE(version2 == version1);
}
TEST_F(Version, SemVer_Extension_Case) {
loot::Version version1, version2;
version1 = loot::Version(std::string("1.0.0-Alpha"));
version2 = loot::Version(std::string("1.0.0-beta"));
EXPECT_TRUE(version1 < version2);
EXPECT_FALSE(version2 < version1);
EXPECT_FALSE(version1 == version2);
EXPECT_FALSE(version2 == version1);
}
#endif