mirror of https://github.com/kiwix/libkiwix.git
[API Break] Fix pathTools (and a bit stringTools).
Api changes : - removeLastPathElement do not takes extra arguments `removePreSeparator` and `removePostSeparator`. This is not needed as path do not need special tailing separator. - Only one function `split`. Arguments can be implicitly convert to string. No need for overloading functions to explicitly cast them. - `split` function takes another argument `trimEmpty`. If true, empty element are removed. Path manipulation now almost pass trough a vector<string> to store each path's part. Most of the complex works is now made in the normalizeParts function.
This commit is contained in:
parent
49c0c5ff47
commit
598dd3c175
|
@ -25,9 +25,7 @@
|
|||
bool isRelativePath(const std::string& path);
|
||||
std::string computeAbsolutePath(const std::string& path, const std::string& relativePath);
|
||||
std::string computeRelativePath(const std::string& path, const std::string& absolutePath);
|
||||
std::string removeLastPathElement(const std::string& path,
|
||||
const bool removePreSeparator = false,
|
||||
const bool removePostSeparator = false);
|
||||
std::string removeLastPathElement(const std::string& path);
|
||||
std::string appendToDirectory(const std::string& directoryPath, const std::string& filename);
|
||||
|
||||
unsigned int getFileSize(const std::string& path);
|
||||
|
|
|
@ -43,10 +43,7 @@ void loadICUExternalTables();
|
|||
std::string urlEncode(const std::string& value, bool encodeReserved = false);
|
||||
std::string urlDecode(const std::string& value, bool component = false);
|
||||
|
||||
std::vector<std::string> split(const std::string&, const std::string&);
|
||||
std::vector<std::string> split(const char*, const char*);
|
||||
std::vector<std::string> split(const std::string&, const char*);
|
||||
std::vector<std::string> split(const char*, const std::string&);
|
||||
std::vector<std::string> split(const std::string&, const std::string&, bool trimEmpty = true);
|
||||
std::string join(const std::vector<std::string>& list, const std::string& sep);
|
||||
|
||||
std::string ucAll(const std::string& word);
|
||||
|
|
|
@ -49,7 +49,7 @@ Aria2::Aria2():
|
|||
m_secret = "token:"+m_secret;
|
||||
|
||||
std::string aria2cmd = appendToDirectory(
|
||||
removeLastPathElement(getExecutablePath(true), true, true),
|
||||
removeLastPathElement(getExecutablePath(true)),
|
||||
ARIA2_CMD);
|
||||
if (fileExists(aria2cmd)) {
|
||||
// A local aria2c exe exists (packaged with kiwix-desktop), use it.
|
||||
|
|
|
@ -36,7 +36,7 @@ void KiwixServe::run()
|
|||
|
||||
std::vector<const char*> callCmd;
|
||||
std::string kiwixServeCmd = appendToDirectory(
|
||||
removeLastPathElement(getExecutablePath(true), true, true),
|
||||
removeLastPathElement(getExecutablePath(true)),
|
||||
KIWIXSERVE_CMD);
|
||||
if (fileExists(kiwixServeCmd)) {
|
||||
// A local kiwix-serve exe exists (packaged with kiwix-desktop), use it.
|
||||
|
|
|
@ -115,7 +115,7 @@ unsigned int Library::getBookCount(const bool localBooks,
|
|||
|
||||
bool Library::writeToFile(const std::string& path)
|
||||
{
|
||||
auto baseDir = removeLastPathElement(path, true, false);
|
||||
auto baseDir = removeLastPathElement(path);
|
||||
LibXMLDumper dumper(this);
|
||||
dumper.setBaseDir(baseDir);
|
||||
return writeTextFile(path, dumper.dumpLibXMLContent(getBooksIds()));
|
||||
|
|
|
@ -59,7 +59,7 @@ bool Manager::parseXmlDom(const pugi::xml_document& doc,
|
|||
|
||||
book.setReadOnly(readOnly);
|
||||
book.updateFromXml(bookNode,
|
||||
removeLastPathElement(libraryPath, true, false));
|
||||
removeLastPathElement(libraryPath));
|
||||
|
||||
/* Update the book properties with the new importer */
|
||||
if (libraryVersion.empty()
|
||||
|
@ -177,7 +177,7 @@ std::string Manager::addBookFromPathAndGetId(const std::string& pathToOpen,
|
|||
if (pathToSave != pathToOpen) {
|
||||
book.setPath(isRelativePath(pathToSave)
|
||||
? computeAbsolutePath(
|
||||
removeLastPathElement(writableLibraryPath, true, false),
|
||||
removeLastPathElement(writableLibraryPath),
|
||||
pathToSave)
|
||||
: pathToSave);
|
||||
}
|
||||
|
|
|
@ -39,11 +39,12 @@
|
|||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef _WIN32
|
||||
const std::string SEPARATOR("\\");
|
||||
#define SEPARATOR "\\"
|
||||
#else
|
||||
const std::string SEPARATOR("/");
|
||||
#define SEPARATOR "/"
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
@ -62,11 +63,63 @@ bool isRelativePath(const std::string& path)
|
|||
#endif
|
||||
}
|
||||
|
||||
std::vector<std::string> normalizeParts(std::vector<std::string> parts, bool absolute)
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
#ifdef _WIN32
|
||||
//Special case if we have a drive directory not at first.
|
||||
//Starts from there.
|
||||
auto it = find_if(parts.rbegin(), parts.rend(),
|
||||
[](const std::string& p) ->bool
|
||||
{ return p.length() == 2 && p[1] == ':'; });
|
||||
if (it != parts.rend()) {
|
||||
parts.erase(parts.begin(), it.base()-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (auto& part: parts) {
|
||||
if (part == "..") {
|
||||
if (absolute) {
|
||||
// We try to remove as far as possible.
|
||||
if (ret.size() > 1) {
|
||||
ret.pop_back();
|
||||
}
|
||||
} else {
|
||||
// We remove only if we can remove it.
|
||||
// Else we add it.
|
||||
if (!ret.empty() && ret.back() != "..") {
|
||||
ret.pop_back();
|
||||
} else {
|
||||
ret.push_back("..");
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (part == "") {
|
||||
#ifndef _WIN32
|
||||
if (ret.empty()) {
|
||||
ret.push_back("");
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
if (part == ".") {
|
||||
continue;
|
||||
}
|
||||
ret.push_back(part);
|
||||
}
|
||||
#ifndef _WIN32
|
||||
if (absolute && ret.size() == 1 && ret.back() == "") {
|
||||
ret.push_back("");
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string computeRelativePath(const std::string& path, const std::string& absolutePath)
|
||||
{
|
||||
std::vector<std::string> pathParts = kiwix::split(path, SEPARATOR);
|
||||
std::vector<std::string> absolutePathParts
|
||||
= kiwix::split(absolutePath, SEPARATOR);
|
||||
auto pathParts = normalizeParts(kiwix::split(path, SEPARATOR, false), false);
|
||||
auto absolutePathParts = kiwix::split(absolutePath, SEPARATOR, false);
|
||||
|
||||
unsigned int commonCount = 0;
|
||||
while (commonCount < pathParts.size()
|
||||
|
@ -75,108 +128,63 @@ std::string computeRelativePath(const std::string& path, const std::string& abso
|
|||
commonCount++;
|
||||
}
|
||||
|
||||
std::string relativePath;
|
||||
#ifdef _WIN32
|
||||
/* On Windows you have a token more because the root is represented
|
||||
by a letter */
|
||||
if (commonCount == 0) {
|
||||
relativePath = ".." + SEPARATOR;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::vector<std::string> relativeParts;
|
||||
for (unsigned int i = commonCount; i < pathParts.size(); i++) {
|
||||
relativePath += ".." + SEPARATOR;
|
||||
relativeParts.push_back("..");
|
||||
}
|
||||
for (unsigned int i = commonCount; i < absolutePathParts.size(); i++) {
|
||||
relativePath += absolutePathParts[i];
|
||||
relativePath += i + 1 < absolutePathParts.size() ? SEPARATOR : "";
|
||||
relativeParts.push_back(absolutePathParts[i]);
|
||||
}
|
||||
return relativePath;
|
||||
return kiwix::join(normalizeParts(relativeParts, false), SEPARATOR);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
# define STRTOK strtok_s
|
||||
#else
|
||||
# define STRTOK strtok_r
|
||||
#endif
|
||||
|
||||
/* Warning: the relative path must be with slashes */
|
||||
std::string computeAbsolutePath(const std::string& path, const std::string& relativePath)
|
||||
{
|
||||
std::string absolutePath;
|
||||
|
||||
std::string absolutePath = path;
|
||||
if (path.empty()) {
|
||||
char* path = NULL;
|
||||
size_t size = 0;
|
||||
|
||||
char* cpath;
|
||||
#ifdef _WIN32
|
||||
path = _getcwd(path, size);
|
||||
cpath = _getcwd(NULL, 0);
|
||||
#else
|
||||
path = getcwd(path, size);
|
||||
cpath = getcwd(NULL, 0);
|
||||
#endif
|
||||
|
||||
absolutePath = std::string(path) + SEPARATOR;
|
||||
} else {
|
||||
absolutePath = path.substr(path.length() - 1, 1) == SEPARATOR
|
||||
? path
|
||||
: path + SEPARATOR;
|
||||
absolutePath = cpath;
|
||||
free(cpath);
|
||||
}
|
||||
|
||||
#if _WIN32
|
||||
char* cRelativePath = _strdup(relativePath.c_str());
|
||||
#else
|
||||
char* cRelativePath = strdup(relativePath.c_str());
|
||||
#endif
|
||||
char* saveptr = nullptr;
|
||||
char* token = STRTOK(cRelativePath, "/", &saveptr);
|
||||
auto absoluteParts = normalizeParts(kiwix::split(absolutePath, SEPARATOR, false), true);
|
||||
auto relativeParts = kiwix::split(relativePath, SEPARATOR, false);
|
||||
|
||||
while (token != NULL) {
|
||||
if (std::string(token) == "..") {
|
||||
absolutePath = removeLastPathElement(absolutePath, true, false);
|
||||
token = STRTOK(NULL, "/", &saveptr);
|
||||
} else if (strcmp(token, ".") && strcmp(token, "")) {
|
||||
absolutePath += std::string(token);
|
||||
token = STRTOK(NULL, "/", &saveptr);
|
||||
if (token != NULL) {
|
||||
absolutePath += SEPARATOR;
|
||||
}
|
||||
} else {
|
||||
token = STRTOK(NULL, "/", &saveptr);
|
||||
}
|
||||
}
|
||||
free(cRelativePath);
|
||||
|
||||
return absolutePath;
|
||||
absoluteParts.insert(absoluteParts.end(), relativeParts.begin(), relativeParts.end());
|
||||
return kiwix::join(normalizeParts(absoluteParts, true), SEPARATOR);
|
||||
}
|
||||
|
||||
std::string removeLastPathElement(const std::string& path,
|
||||
const bool removePreSeparator,
|
||||
const bool removePostSeparator)
|
||||
std::string removeLastPathElement(const std::string& path)
|
||||
{
|
||||
std::string newPath = path;
|
||||
size_t offset = newPath.find_last_of(SEPARATOR);
|
||||
if (removePreSeparator &&
|
||||
#ifndef _WIN32
|
||||
offset != newPath.find_first_of(SEPARATOR) &&
|
||||
#endif
|
||||
offset == newPath.length() - 1) {
|
||||
newPath = newPath.substr(0, offset);
|
||||
offset = newPath.find_last_of(SEPARATOR);
|
||||
auto parts = normalizeParts(kiwix::split(path, SEPARATOR, false), false);
|
||||
if (!parts.empty()) {
|
||||
parts.pop_back();
|
||||
}
|
||||
newPath = removePostSeparator ? newPath.substr(0, offset)
|
||||
: newPath.substr(0, offset + 1);
|
||||
return newPath;
|
||||
return kiwix::join(parts, SEPARATOR);
|
||||
}
|
||||
|
||||
std::string appendToDirectory(const std::string& directoryPath, const std::string& filename)
|
||||
{
|
||||
std::string newPath = directoryPath + SEPARATOR + filename;
|
||||
std::string newPath = directoryPath;
|
||||
if (!directoryPath.empty() && directoryPath.back() != SEPARATOR[0]) {
|
||||
newPath += SEPARATOR;
|
||||
}
|
||||
newPath += filename;
|
||||
return newPath;
|
||||
}
|
||||
|
||||
std::string getLastPathElement(const std::string& path)
|
||||
{
|
||||
return path.substr(path.find_last_of(SEPARATOR) + 1);
|
||||
auto parts = normalizeParts(kiwix::split(path, SEPARATOR), false);
|
||||
if (parts.empty()) {
|
||||
return "";
|
||||
}
|
||||
return parts.back();
|
||||
}
|
||||
|
||||
unsigned int getFileSize(const std::string& path)
|
||||
|
|
|
@ -267,37 +267,28 @@ std::string kiwix::urlDecode(const std::string& value, bool component)
|
|||
|
||||
/* Split string in a token array */
|
||||
std::vector<std::string> kiwix::split(const std::string& str,
|
||||
const std::string& delims = " *-")
|
||||
const std::string& delims,
|
||||
bool trimEmpty)
|
||||
{
|
||||
std::string::size_type lastPos = str.find_first_not_of(delims, 0);
|
||||
std::string::size_type pos = str.find_first_of(delims, lastPos);
|
||||
std::string::size_type lastPos = 0;
|
||||
std::string::size_type pos = 0;
|
||||
std::vector<std::string> tokens;
|
||||
|
||||
while (std::string::npos != pos || std::string::npos != lastPos) {
|
||||
tokens.push_back(str.substr(lastPos, pos - lastPos));
|
||||
lastPos = str.find_first_not_of(delims, pos);
|
||||
pos = str.find_first_of(delims, lastPos);
|
||||
while( (pos = str.find_first_of(delims, lastPos)) < str.length() )
|
||||
{
|
||||
auto token = str.substr(lastPos, pos - lastPos);
|
||||
if (!trimEmpty || !token.empty()) {
|
||||
tokens.push_back(token);
|
||||
}
|
||||
lastPos = pos + 1;
|
||||
}
|
||||
|
||||
auto token = str.substr(lastPos);
|
||||
if (!trimEmpty || !token.empty()) {
|
||||
tokens.push_back(token);
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
std::vector<std::string> kiwix::split(const char* lhs, const char* rhs)
|
||||
{
|
||||
const std::string m1(lhs), m2(rhs);
|
||||
return split(m1, m2);
|
||||
}
|
||||
|
||||
std::vector<std::string> kiwix::split(const char* lhs, const std::string& rhs)
|
||||
{
|
||||
return split(lhs, rhs.c_str());
|
||||
}
|
||||
|
||||
std::vector<std::string> kiwix::split(const std::string& lhs, const char* rhs)
|
||||
{
|
||||
return split(lhs.c_str(), rhs);
|
||||
}
|
||||
|
||||
std::string kiwix::join(const std::vector<std::string>& list, const std::string& sep)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
|
|
@ -5,7 +5,8 @@ tests = [
|
|||
'library',
|
||||
'regex',
|
||||
'tagParsing',
|
||||
'stringTools'
|
||||
'stringTools',
|
||||
'pathTools'
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Matthieu Gautier
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
|
||||
* NON-INFRINGEMENT. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "../include/tools/pathTools.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# define S "\\"
|
||||
# define AS "c:"
|
||||
#else
|
||||
# define S "/"
|
||||
# define AS ""
|
||||
#endif
|
||||
|
||||
#define P2(a, b) a S b
|
||||
#define P3(a, b, c) P2(P2(a, b), c)
|
||||
#define P4(a, b, c, d) P2(P3(a, b, c), d)
|
||||
#define P5(a, b, c, d, e) P2(P4(a, b, c, d), e)
|
||||
#define P6(a, b, c, d, e, f) P2(P5(a, b, c ,d, e), f)
|
||||
|
||||
#define A1(a) P2(AS,a)
|
||||
#define A2(a, b) A1(P2(a, b))
|
||||
#define A3(a, b, c) A1(P3(a, b, c))
|
||||
#define A4(a, b, c, d) A1(P4(a, b, c, d))
|
||||
#define A5(a, b, c, d, e) A1(P5(a, b, c, d, e))
|
||||
|
||||
std::vector<std::string> normalizeParts(std::vector<std::string> parts, bool absolute);
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
#define V std::vector<std::string>
|
||||
TEST(pathTools, normalizePartsAbsolute)
|
||||
{
|
||||
#define N(...) normalizeParts(__VA_ARGS__, true)
|
||||
ASSERT_EQ(N({}), V({}));
|
||||
#ifdef _WIN32
|
||||
ASSERT_EQ(N({"c:"}), V({"c:"}));
|
||||
#else
|
||||
ASSERT_EQ(N({""}), V({"", ""}));
|
||||
#endif
|
||||
ASSERT_EQ(N({AS, "a"}), V({AS, "a"}));
|
||||
ASSERT_EQ(N({AS, "a", "b"}), V({AS, "a", "b"}));
|
||||
ASSERT_EQ(N({AS, "a", "b", ".."}), V({AS, "a"}));
|
||||
#ifdef _WIN32
|
||||
ASSERT_EQ(N({AS, "a", "b", "..", ".."}), V({AS}));
|
||||
#else
|
||||
ASSERT_EQ(N({AS, "a", "b", "..", ".."}), V({AS, ""}));
|
||||
#endif
|
||||
ASSERT_EQ(N({AS, "a", "b", "..", "..", "..", "foo"}), V({AS, "foo"}));
|
||||
ASSERT_EQ(N({AS, "..", "..", "c", "d", ".", "..", "foo"}), V({AS, "c", "foo"}));
|
||||
ASSERT_EQ(N({AS, "a", "b", ".", "c", "d", "..", "foo"}), V({AS, "a", "b", "c", "foo"}));
|
||||
|
||||
#ifdef _WIN32
|
||||
ASSERT_EQ(N({"c:", "a", "b", ".", "c", "d:", "..", "foo"}), V({"d:", "foo"}));
|
||||
#endif
|
||||
#undef N
|
||||
}
|
||||
|
||||
TEST(pathTools, normalizePartsRelative)
|
||||
{
|
||||
#define N(...) normalizeParts(__VA_ARGS__, false)
|
||||
ASSERT_EQ(N({}), V({}));
|
||||
ASSERT_EQ(N({""}), V({""}));
|
||||
ASSERT_EQ(N({"a"}), V({"a"}));
|
||||
ASSERT_EQ(N({"a", "b"}), V({"a", "b"}));
|
||||
ASSERT_EQ(N({"a", "b", ".."}), V({"a"}));
|
||||
ASSERT_EQ(N({"a", "b", "..", ".."}), V({}));
|
||||
ASSERT_EQ(N({"a", "b", "..", "..", "..", "foo"}), V({"..", "foo"}));
|
||||
ASSERT_EQ(N({"..", "..", "c", "d", ".", "..", "foo"}), V({"..", "..", "c", "foo"}));
|
||||
ASSERT_EQ(N({"a", "b", ".", "c", "d", "..", "foo"}), V({"a", "b", "c", "foo"}));
|
||||
#undef N
|
||||
}
|
||||
|
||||
TEST(pathTools, isRelativePath)
|
||||
{
|
||||
ASSERT_TRUE(isRelativePath("foo"));
|
||||
ASSERT_TRUE(isRelativePath(P2("foo","bar")));
|
||||
ASSERT_TRUE(isRelativePath(P3(".","foo","bar")));
|
||||
ASSERT_TRUE(isRelativePath(P2("..","foo")));
|
||||
ASSERT_TRUE(isRelativePath(P4("foo","","bar","")));
|
||||
ASSERT_FALSE(isRelativePath(A1("foo")));
|
||||
ASSERT_FALSE(isRelativePath(A2("foo", "bar")));
|
||||
}
|
||||
|
||||
TEST(pathTools, computeAbsolutePath)
|
||||
{
|
||||
ASSERT_EQ(computeAbsolutePath(A2("a","b"), "foo"),
|
||||
A3("a","b","foo"));
|
||||
ASSERT_EQ(computeAbsolutePath(A3("a","b",""), "foo"),
|
||||
A3("a","b","foo"));
|
||||
ASSERT_EQ(computeAbsolutePath(A2("a","b"), P2(".","foo")),
|
||||
A3("a","b","foo"));
|
||||
ASSERT_EQ(computeAbsolutePath(A2("a","b"), P2("..","foo")),
|
||||
A2("a","foo"));
|
||||
ASSERT_EQ(computeAbsolutePath(A3("a","b",""), P2("..","foo")),
|
||||
A2("a","foo"));
|
||||
ASSERT_EQ(computeAbsolutePath(A5("a","b","c","d","e"), P2("..","foo")),
|
||||
A5("a","b","c","d","foo"));
|
||||
ASSERT_EQ(computeAbsolutePath(A5("a","b","c","d","e"), P5("..","..","..","g","foo")),
|
||||
A4("a","b","g","foo"));
|
||||
}
|
||||
|
||||
TEST(pathTools, computeRelativePath)
|
||||
{
|
||||
ASSERT_EQ(computeRelativePath(A2("a","b"), A3("a","b","foo")),
|
||||
"foo");
|
||||
ASSERT_EQ(computeRelativePath(A3("a","b",""), A3("a","b","foo")),
|
||||
"foo");
|
||||
ASSERT_EQ(computeRelativePath(A2("a","b"), A2("a","foo")),
|
||||
P2("..","foo"));
|
||||
ASSERT_EQ(computeRelativePath(A3("a","b",""), A2("a","foo")),
|
||||
P2("..","foo"));
|
||||
ASSERT_EQ(computeRelativePath(A5("a","b","c","d","e"), A5("a","b","c","d","foo")),
|
||||
P2("..","foo"));
|
||||
ASSERT_EQ(computeRelativePath(A5("a","b","c","d","e"), A4("a","b","g","foo")),
|
||||
P5("..","..","..","g","foo"));
|
||||
}
|
||||
|
||||
TEST(pathTools, removeLastPathElement)
|
||||
{
|
||||
ASSERT_EQ(removeLastPathElement(P3("a","b","c")),
|
||||
P2("a","b"));
|
||||
ASSERT_EQ(removeLastPathElement(A3("a","b","c")),
|
||||
A2("a","b"));
|
||||
ASSERT_EQ(removeLastPathElement(P4("a","b","c","")),
|
||||
P2("a","b"));
|
||||
ASSERT_EQ(removeLastPathElement(A4("a","b","c","")),
|
||||
A2("a","b"));
|
||||
}
|
||||
|
||||
TEST(pathTools, appendToDirectory)
|
||||
{
|
||||
ASSERT_EQ(appendToDirectory(P3("a","b","c"), "foo.xml"),
|
||||
P4("a","b","c","foo.xml"));
|
||||
ASSERT_EQ(appendToDirectory(P4("a","b","c",""), "foo.xml"),
|
||||
P4("a","b","c","foo.xml"));
|
||||
ASSERT_EQ(appendToDirectory(P3("a","b","c"), P2("d","foo.xml")),
|
||||
P5("a","b","c","d","foo.xml"));
|
||||
ASSERT_EQ(appendToDirectory(P4("a","b","c",""), P2("d","foo.xml")),
|
||||
P5("a","b","c","d","foo.xml"));
|
||||
ASSERT_EQ(appendToDirectory(P3("a","b","c"), P2(".","foo.xml")),
|
||||
P5("a","b","c",".","foo.xml"));
|
||||
ASSERT_EQ(appendToDirectory(P4("a","b","c",""), P2(".","foo.xml")),
|
||||
P5("a","b","c",".","foo.xml"));
|
||||
}
|
||||
|
||||
|
||||
TEST(pathTools, goUp)
|
||||
{
|
||||
ASSERT_EQ(computeAbsolutePath(A3("a","b","c"), ".."),
|
||||
A2("a", "b"));
|
||||
ASSERT_EQ(computeAbsolutePath(A3("a","b","c"), P2("..","..")),
|
||||
A1("a"));
|
||||
#ifdef _WIN32
|
||||
ASSERT_EQ(computeAbsolutePath(A3("a","b","c"), P3("..","..","..")),
|
||||
"c:");
|
||||
ASSERT_EQ(computeAbsolutePath(A3("a","b","c"), P4("..","..","..","..")),
|
||||
"c:");
|
||||
#else
|
||||
ASSERT_EQ(computeAbsolutePath(A3("a","b","c"), P3("..","..","..")),
|
||||
"/");
|
||||
ASSERT_EQ(computeAbsolutePath(A3("a","b","c"), P4("..","..","..","..")),
|
||||
"/");
|
||||
#endif
|
||||
|
||||
|
||||
ASSERT_EQ(computeAbsolutePath(A3("a","b","c"), P2("..", "foo")),
|
||||
A3("a", "b","foo"));
|
||||
ASSERT_EQ(computeAbsolutePath(A3("a","b","c"), P3("..","..","foo")),
|
||||
A2("a","foo"));
|
||||
ASSERT_EQ(computeAbsolutePath(A3("a","b","c"), P4("..","..","..","foo")),
|
||||
A1("foo"));
|
||||
ASSERT_EQ(computeAbsolutePath(A3("a","b","c"), P5("..","..","..","..","foo")),
|
||||
A1("foo"));
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST(pathTools, dirChange)
|
||||
{
|
||||
std::string p1("c:\\a\\b\\c");
|
||||
std::string p2("d:\\d\\e\\foo.xml");
|
||||
std::string relative_path = computeRelativePath(p1, p2);
|
||||
ASSERT_EQ(relative_path, "d:\\d\\e\\foo.xml");
|
||||
std::string abs_path = computeAbsolutePath(p1, relative_path);
|
||||
ASSERT_EQ(abs_path, p2);
|
||||
ASSERT_EQ(computeAbsolutePath(p1, "..\\..\\..\\..\\..\\d:\\d\\e\\foo.xml"), p2);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
};
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
namespace kiwix {
|
||||
std::string join(const std::vector<std::string>& list, const std::string& sep);
|
||||
std::vector<std::string> split(const std::string& base, const std::string& sep, bool trimEmpty);
|
||||
};
|
||||
|
||||
using namespace kiwix;
|
||||
|
@ -36,6 +37,22 @@ TEST(stringTools, join)
|
|||
ASSERT_EQ(join(list, ";"), "a;b;c");
|
||||
}
|
||||
|
||||
TEST(stringTools, split)
|
||||
{
|
||||
std::vector<std::string> list1 = { "a", "b", "c" };
|
||||
ASSERT_EQ(split("a;b;c", ";", false), list1);
|
||||
ASSERT_EQ(split("a;b;c", ";", true), list1);
|
||||
std::vector<std::string> list2 = { "", "a", "b", "c" };
|
||||
ASSERT_EQ(split(";a;b;c", ";", false), list2);
|
||||
ASSERT_EQ(split(";a;b;c", ";", true), list1);
|
||||
std::vector<std::string> list3 = { "", "a", "b", "c", ""};
|
||||
ASSERT_EQ(split(";a;b;c;", ";", false), list3);
|
||||
ASSERT_EQ(split(";a;b;c;", ";", true), list1);
|
||||
std::vector<std::string> list4 = { "", "a", "b", "", "c", ""};
|
||||
ASSERT_EQ(split(";a;b;;c;", ";", false), list4);
|
||||
ASSERT_EQ(split(";a;b;;c;", ";", true), list1);
|
||||
}
|
||||
|
||||
};
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue