--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file path.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @version 1.0
+ */
+#ifndef PATH_H
+#define PATH_H
+
+#include <dirent.h>
+#include <sys/stat.h>
+
+#include <string>
+#include <sstream>
+#include <iterator>
+#include <memory>
+#include <vector>
+
+#include <dpl/exception.h>
+#include <dpl/string.h>
+
+namespace DPL {
+namespace Utils {
+class Path;
+}
+}
+
+std::ostream & operator<<(std::ostream & str, const DPL::Utils::Path & path);
+
+namespace DPL {
+namespace Utils {
+/**
+ * @brief The Path class path abstraction
+ *
+ * Class for expressing paths not limited not existing ones.
+ * It's possible to check if path exists, remove it or iterate it if it's directory
+ */
+class Path
+{
+public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, BaseException)
+ DECLARE_EXCEPTION_TYPE(BaseException, AlreadyExists)
+ DECLARE_EXCEPTION_TYPE(BaseException, NotExists)
+ DECLARE_EXCEPTION_TYPE(BaseException, NotDirectory)
+ DECLARE_EXCEPTION_TYPE(BaseException, OperationFailed)
+ DECLARE_EXCEPTION_TYPE(BaseException, EmptyPath)
+ DECLARE_EXCEPTION_TYPE(BaseException, InternalError)
+
+ class Iterator : public std::iterator<std::input_iterator_tag, Path>
+ {
+ public:
+ Iterator();
+ Iterator(const char *);
+ Iterator& operator++();
+ Iterator operator++(int);
+ bool operator==(const Iterator& rhs) const;
+ bool operator!=(const Iterator& rhs) const;
+ const Path & operator*();
+ const Path * operator->();
+ private:
+ void ReadNext();
+
+ std::shared_ptr<DIR> m_dir;
+ std::shared_ptr<Path> m_path;
+ std::shared_ptr<Path> m_root;
+ };
+
+ explicit Path(const DPL::String & str);
+ explicit Path(const std::string & str);
+ explicit Path(const char * str);
+
+ /**
+ * @brief DirectoryName shell's dirname equivalent
+ * @return directory name of given path
+ */
+ std::string DirectoryName() const;
+ /**
+ * @brief Basename shell's basename equivalent
+ * @return base name of given path
+ */
+ std::string Basename() const;
+ /**
+ * @brief Fullpath fullpath based on current working diretory
+ * @return full path
+ */
+ std::string Fullpath() const;
+
+ bool Exists() const;
+ bool IsDir() const;
+ bool IsFile() const;
+ bool IsSymlink() const;
+
+ bool operator==(const Path & other) const;
+ bool operator!=(const Path & other) const;
+
+ //appending to path
+ Path operator/(const DPL::String& part) const;
+ Path operator/(const std::string& part) const;
+ Path operator/(const char * part) const;
+
+ Path & operator/=(const DPL::String& part);
+ Path & operator/=(const std::string& part);
+ Path & operator/=(const char * part);
+
+ //foreach
+ Iterator begin() const;
+ Iterator end() const;
+
+private:
+ Path();
+
+ void Append(const std::string& part);
+ void Construct(const std::string & src);
+
+ std::vector<std::string> m_parts;
+
+ friend std::ostream & ::operator<<(std::ostream & str, const DPL::Utils::Path & path);
+};
+
+/**
+ * @brief MkDir creates 'current path' as directory
+ * @param path path
+ * @param mode mode
+ */
+void MakeDir(const Path & path, mode_t mode = 0755);
+
+/**
+ * @brief MkFile creates 'current path' as empty file
+ * @param path path
+ */
+void MakeEmptyFile(const Path & path);
+
+/**
+ * @brief Remove removes 'current path'
+ * @param path path to remove
+ */
+void Remove(const Path & path);
+
+/**
+ * @brief Rename renames(moves) current path
+ *
+ * If you uses this method string to path is internally change
+ * and this object will store new path not only anymore
+ * @param from source path
+ * @param to target path
+ */
+void Rename(const Path & from, const Path & to);
+
+/**
+ * @brief Exists Checks if given path exists
+ * @param path path
+ * @return true if path exists
+ */
+bool Exists(const Path & path);
+
+}
+
+}
+
+//TODO: uncomment when user defiend literals are supported
+///Path operator"" p(const char * str);
+
+#endif // PATH_H
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file path.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @version 1.0
+ */
+
+#include "dpl/utils/path.h"
+
+#include <dpl/utils/wrt_utility.h>
+
+#include <dpl/scoped_free.h>
+#include <dpl/errno_string.h>
+#include <dpl/file_input.h>
+#include <dpl/file_output.h>
+#include <dpl/copy.h>
+
+#include <sys/stat.h>
+
+namespace DPL {
+
+namespace Utils {
+
+Path::Iterator::Iterator() //end iterator by default
+{
+}
+
+Path::Iterator::Iterator(const char * str)
+{
+ m_root = std::shared_ptr<Path>(new Path(str));
+ m_dir = std::shared_ptr<DIR>(opendir(str), [](DIR * d){ if(d)closedir(d); }); //custom delete
+ if(m_dir.get() == NULL)
+ {
+ ThrowMsg(NotDirectory, "Not directory");
+ }
+ ReadNext();
+}
+
+Path::Iterator& Path::Iterator::operator++()
+{
+ ReadNext();
+ return *this;
+}
+
+Path::Iterator Path::Iterator::operator++(int)
+{
+ Path::Iterator copy(*this);
+ ReadNext();
+ return copy;
+}
+
+void Path::Iterator::ReadNext()
+{
+ struct dirent * entry = readdir(m_dir.get());
+ while(entry && (strcmp(entry->d_name, ".") == 0 ||
+ strcmp(entry->d_name, "..") == 0))
+ {
+ entry = readdir(m_dir.get());
+ }
+ if(entry)
+ {
+ m_path = std::shared_ptr<Path>(new Path(*m_root));
+ m_path->Append(entry->d_name);
+ }
+ else //transform into end iterator
+ {
+ m_path.reset();
+ m_dir.reset();
+ }
+}
+
+bool Path::Iterator::operator==(const Path::Iterator& rhs) const
+{
+ if(m_dir.get() == NULL)
+ {
+ if(rhs.m_dir.get() == NULL) return true;
+ else return false;
+ }
+ else
+ {
+ if(rhs.m_dir.get() == NULL) return false;
+ }
+ return *m_path == *rhs.m_path;
+}
+
+bool Path::Iterator::operator!=(const Path::Iterator& rhs) const
+{
+ return !this->operator==(rhs);
+}
+
+const Path & Path::Iterator::operator*()
+{
+ return *m_path;
+}
+
+const Path * Path::Iterator::operator->()
+{
+ return m_path.get();
+}
+
+Path::Path(const DPL::String & str)
+{
+ Construct(ToUTF8String(str));
+}
+
+Path::Path(const std::string & str)
+{
+ Construct(str);
+}
+
+Path::Path(const char * str)
+{
+ Construct(std::string(str));
+}
+
+void Path::Construct(const std::string & src)
+{
+ if(src.empty()) ThrowMsg(EmptyPath, "Path cannot be empty");
+ if(src[0] != '/')
+ {
+ DPL::ScopedFree<char> root(getcwd(NULL,0));
+ Tokenize(std::string(root.Get()), "\\/", std::inserter(m_parts, m_parts.begin()), true);
+ }
+ Tokenize(src, "\\/", std::inserter(m_parts, m_parts.end()), true);
+}
+
+Path::Path() //for private usage
+{
+}
+
+std::string Path::DirectoryName() const
+{
+ if(m_parts.empty()) ThrowMsg(InternalError, "Asking DirectoryName for root directory");
+ std::string ret = Join(m_parts.begin(), --m_parts.end(), "/");
+ return std::string("/") + ret;
+}
+
+std::string Path::Basename() const
+{
+ if(m_parts.empty()) return "";
+ else return m_parts.back();
+}
+
+std::string Path::Fullpath() const
+{
+ std::string ret = Join(m_parts.begin(), m_parts.end(), "/");
+ return std::string ("/") + ret;
+}
+
+//foreach
+Path::Iterator Path::begin() const
+{
+ if(IsDir())
+ {
+ return Iterator(Fullpath().c_str());
+ }
+ else
+ {
+ ThrowMsg(NotDirectory, "Cannot iterate not a directory");
+ }
+}
+
+Path::Iterator Path::end() const
+{
+ return Iterator();
+}
+
+
+bool Path::Exists() const
+{
+ struct stat tmp;
+ return (0 == lstat(Fullpath().c_str(), &tmp));
+}
+
+bool Path::IsDir() const
+{
+ struct stat tmp;
+ if (-1 == lstat(Fullpath().c_str(), &tmp))
+ {
+ ThrowMsg(NotExists, DPL::GetErrnoString());
+ }
+ return S_ISDIR(tmp.st_mode);
+}
+
+bool Path::IsFile() const
+{
+ struct stat tmp;
+ if (-1 == lstat(Fullpath().c_str(), &tmp))
+ {
+ ThrowMsg(NotExists, DPL::GetErrnoString());
+ }
+ return S_ISREG(tmp.st_mode);
+}
+
+bool Path::IsSymlink() const
+{
+ struct stat tmp;
+ if (-1 == lstat(Fullpath().c_str(), &tmp))
+ {
+ ThrowMsg(NotExists, DPL::GetErrnoString());
+ }
+ return S_ISLNK(tmp.st_mode);
+}
+
+bool Path::operator==(const Path & other) const
+{
+ return m_parts == other.m_parts;
+}
+
+bool Path::operator!=(const Path & other) const
+{
+ return m_parts != other.m_parts;
+}
+
+Path Path::operator/(const DPL::String& part) const
+{
+ Path newOne;
+ newOne.Append(ToUTF8String(part));
+ return newOne;
+}
+
+Path Path::operator/(const std::string& part) const
+{
+ Path newOne;
+ newOne.Append(part);
+ return newOne;
+}
+
+Path Path::operator/(const char * part) const
+{
+ Path newOne(*this);
+ newOne.Append(std::string(part));
+ return newOne;
+}
+
+Path & Path::operator/=(const DPL::String& part)
+{
+ Append(ToUTF8String(part));
+}
+
+Path & Path::operator/=(const std::string& part)
+{
+ Append(part);
+}
+
+Path & Path::operator/=(const char * part)
+{
+ Append(std::string(part));
+}
+
+void Path::Append(const std::string& part)
+{
+ std::vector<std::string> tokens;
+ Tokenize(part, "\\/", std::inserter(tokens, tokens.end()), true);
+ std::copy(tokens.begin(), tokens.end(), std::inserter(m_parts, m_parts.end()));
+}
+
+void MakeDir(const Path & path, mode_t mode)
+{
+ if(!WrtUtilMakeDir(path.Fullpath(), mode)) ThrowMsg(Path::OperationFailed, "Cannot make directory");
+}
+
+void MakeEmptyFile(const Path & path)
+{
+ std::string fp = path.Fullpath();
+ FILE* fd = fopen(fp.c_str(), "wx");
+ if(!fd)
+ {
+ struct stat st;
+ if(lstat(fp.c_str(), &st) == 0)
+ {
+ ThrowMsg(Path::AlreadyExists, "File already exists");
+ }
+ else
+ {
+ ThrowMsg(Path::OperationFailed, "Operation failed");
+ }
+ }
+ fclose(fd);
+}
+
+void Remove(const Path & path)
+{
+ if(!WrtUtilRemove(path.Fullpath())) ThrowMsg(Path::OperationFailed, "Cannot remove path");
+}
+
+void Rename(const Path & from, const Path & to)
+{
+ if(from == to)
+ {
+ return;
+ }
+ int code = 0;
+ if( (code = rename(from.Fullpath().c_str(), to.Fullpath().c_str())) )
+ {
+ if(code == EXDEV)
+ {
+ Try
+ {
+ DPL::FileInput in(from.Fullpath());
+ DPL::FileOutput out(to.Fullpath());
+ DPL::Copy(&in, &out);
+ }
+ Catch(DPL::FileInput::Exception::Base)
+ {
+ ThrowMsg(Path::OperationFailed, "Cannot open input file " << from.Fullpath());
+ }
+ Catch(DPL::FileOutput::Exception::Base)
+ {
+ ThrowMsg(Path::OperationFailed, "Cannot open output file " << to.Fullpath());
+ }
+ }
+ else
+ {
+ ThrowMsg(Path::OperationFailed, DPL::GetErrnoString());
+ }
+ }
+}
+
+bool Exists(const Path & path)
+{
+ return path.Exists();
+}
+
+}
+
+}
+
+std::ostream & operator<<(std::ostream & str, const DPL::Utils::Path & path)
+{
+ str << path.Fullpath();
+ return str;
+}
+
+//TODO: uncomment when used defiend literals are supported
+///DPL::Utils::Path operator""p(const char * str, size_t)
+//{
+// return DPL::Utils::Path(str);
+//}
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file path.h
+ * @author Tomasz Iwanek (t.iwanek@samsung.com)
+ * @version 1.0
+ */
+
+#include <set>
+#include <memory>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/scoped_dir.h>
+#include <dpl/scoped_free.h>
+#include <dpl/utils/path.h>
+#include <dpl/foreach.h>
+#include <dpl/log/log.h>
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+using namespace DPL::Utils;
+
+namespace {
+//do not used path here we test it
+std::string rootTest = "/tmp/wrttest/";
+}
+
+RUNNER_TEST_GROUP_INIT(DPL_Path)
+
+/*
+Name: path_touch
+Description: constructs paths in many ways
+Expected: success full constrution
+*/
+RUNNER_TEST(path_mkfile)
+{
+ DPL::ScopedDir sd(rootTest);
+
+ struct stat st;
+ Path path = Path(rootTest) / "touch.txt";
+ RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) != 0, "File should not be created");
+ RUNNER_ASSERT(!path.Exists());
+ MakeEmptyFile(path);
+ RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "File should be created");
+ RUNNER_ASSERT(path.Exists());
+ RUNNER_ASSERT(path.IsFile());
+ RUNNER_ASSERT(!path.IsDir());
+ RUNNER_ASSERT(!path.IsSymlink());
+}
+
+/*
+Name: path_touch
+Description: tries to craete file when it exists
+Expected: failure
+*/
+RUNNER_TEST(path_mkfile_exists)
+{
+ DPL::ScopedDir sd(rootTest);
+
+ Path path = Path(rootTest) / "touch.txt";
+ MakeEmptyFile(path);
+ RUNNER_ASSERT(path.Exists());
+ bool cannotCreate2ndTime = false;
+ Try
+ {
+ MakeEmptyFile(path);
+ }
+ Catch(Path::AlreadyExists)
+ {
+ cannotCreate2ndTime = true;
+ }
+ RUNNER_ASSERT_MSG(cannotCreate2ndTime, "File created should not be able to be created second time");
+}
+
+/*
+Name: path_mkfile_invalid_path
+Description: tries to create file in not exisitng directory
+Expected: failure at creation
+*/
+RUNNER_TEST(path_mkfile_invalid_path)
+{
+ DPL::ScopedDir sd(rootTest);
+
+ Path path = Path(rootTest) / "not_existing" / "touch.txt";
+ bool cannotCreate = false;
+ Try
+ {
+ MakeEmptyFile(path);
+ }
+ Catch(Path::OperationFailed)
+ {
+ cannotCreate = true;
+ }
+ RUNNER_ASSERT_MSG(cannotCreate, "File created should not be able to be created");
+}
+
+/*
+Name: path_mkdir
+Description: creates valid directory
+Expected: success direcotry creation
+*/
+RUNNER_TEST(path_mkdir)
+{
+ DPL::ScopedDir sd(rootTest);
+
+ struct stat st;
+ Path path = Path(rootTest) / "touchDir";
+ RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) != 0, "Directory should not be created");
+ RUNNER_ASSERT(!path.Exists());
+ MakeDir(path);
+ RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "Directory should be created");
+ RUNNER_ASSERT(path.Exists());
+ RUNNER_ASSERT(!path.IsFile());
+ RUNNER_ASSERT(path.IsDir());
+ RUNNER_ASSERT(!path.IsSymlink());
+}
+
+/*
+Name: path_symlink
+Description: chekc if symlink is correctly recognized
+Expected: method isSymlink returns true
+*/
+RUNNER_TEST(path_symlink)
+{
+ DPL::ScopedDir sd(rootTest);
+
+ struct stat st;
+ Path path = Path(rootTest) / "symlink";
+ RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) != 0, "Symlink should not be created");
+ RUNNER_ASSERT(!path.Exists());
+ (void)symlink("/nonexistisfile/file/file/file ", path.Fullpath().c_str());
+ RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "Symlink should be created");
+ RUNNER_ASSERT(path.Exists());
+ RUNNER_ASSERT(!path.IsFile());
+ RUNNER_ASSERT(!path.IsDir());
+ RUNNER_ASSERT(path.IsSymlink());
+}
+
+/*
+Name: path_construction_empty
+Description: tries to construct empty path
+Expected: failure
+*/
+RUNNER_TEST(path_construction_empty)
+{
+ bool passed = false;
+ Try
+ {
+ Path path1(std::string(""));
+ }
+ Catch(Path::EmptyPath)
+ {
+ passed = true;
+ }
+ RUNNER_ASSERT_MSG(passed, "Construction with empty path do not fails");
+}
+
+/*
+Name: path_construction_root
+Description: tries to construct root path
+Expected: success
+*/
+RUNNER_TEST(path_construction_root)
+{
+ Path path1(std::string("/"));
+ RUNNER_ASSERT(path1.Fullpath() == "/");
+ RUNNER_ASSERT(path1.Basename() == "");
+ bool passed = false;
+ Try
+ {
+ RUNNER_ASSERT(path1.DirectoryName() == "/");
+ }
+ Catch(Path::InternalError)
+ {
+ passed = true;
+ }
+ RUNNER_ASSERT_MSG(passed, "Directory name for root should be an error");
+}
+
+/*
+Name: path_construction_1
+Description: constructs paths in many ways
+Expected: success full constrution
+*/
+RUNNER_TEST(path_construction_1)
+{
+ DPL::ScopedFree<char> sf(getcwd(NULL, 0));
+
+ Path path1(std::string("/test/bin/file"));
+ RUNNER_ASSERT(path1.Fullpath() == "/test/bin/file");
+ RUNNER_ASSERT(path1.Basename() == "file");
+ RUNNER_ASSERT(path1.DirectoryName() == "/test/bin");
+}
+
+/*
+Name: path_construction_2
+Description: constructs paths in many ways
+Expected: success full constrution
+*/
+RUNNER_TEST(path_construction_2)
+{
+ DPL::ScopedFree<char> sf(getcwd(NULL, 0));
+ std::string cwd(sf.Get());
+
+ Path path2(std::string("test/bin/file.eas"));
+ RUNNER_ASSERT(path2.Fullpath() == cwd + "/test/bin/file.eas");
+ RUNNER_ASSERT(path2.Basename() == "file.eas");
+ RUNNER_ASSERT(path2.DirectoryName() == cwd + "/test/bin");
+}
+
+/*
+Name: path_construction_3
+Description: constructs paths in many ways
+Expected: success full constrution
+*/
+RUNNER_TEST(path_construction_3)
+{
+ DPL::ScopedFree<char> sf(getcwd(NULL, 0));
+ std::string cwd(sf.Get());
+
+ Path path3("test/23/abc");
+ RUNNER_ASSERT(path3.Fullpath() == cwd + "/test/23/abc");
+ RUNNER_ASSERT(path3.Basename() == "abc");
+ RUNNER_ASSERT(path3.DirectoryName() == cwd + "/test/23");
+}
+
+/*
+Name: path_construction_4
+Description: constructs paths in many ways
+Expected: success full constrution
+*/
+RUNNER_TEST(path_construction_4)
+{
+ DPL::ScopedFree<char> sf(getcwd(NULL, 0));
+
+ Path path4("/test/bin/abc");
+ RUNNER_ASSERT(path4.Fullpath() == "/test/bin/abc");
+ RUNNER_ASSERT(path4.Basename() == "abc");
+ RUNNER_ASSERT(path4.DirectoryName() == "/test/bin");
+}
+
+/*
+Name: path_construction_5
+Description: constructs paths in many ways
+Expected: success full constrution
+*/
+RUNNER_TEST(path_construction_5)
+{
+ DPL::ScopedFree<char> sf(getcwd(NULL, 0));
+ std::string cwd(sf.Get());
+
+ Path path5(DPL::String(L"test/bin/file.st.exe"));
+ RUNNER_ASSERT(path5.Fullpath() == cwd + "/test/bin/file.st.exe");
+ RUNNER_ASSERT(path5.Basename() == "file.st.exe");
+ RUNNER_ASSERT(path5.DirectoryName() == cwd + "/test/bin");
+}
+
+/*
+Name: path_construction_6
+Description: constructs paths in many ways
+Expected: success full constrution
+*/
+RUNNER_TEST(path_construction_6)
+{
+ DPL::ScopedFree<char> sf(getcwd(NULL, 0));
+
+ Path path6(DPL::String(L"/test/bin/file"));
+ RUNNER_ASSERT(path6.Fullpath() == "/test/bin/file");
+ RUNNER_ASSERT(path6.Basename() == "file");
+ RUNNER_ASSERT(path6.DirectoryName() == "/test/bin");
+}
+
+/*
+Name: path_construction_7
+Description: constructs paths in many ways
+Expected: success full constrution
+*/
+RUNNER_TEST(path_construction_7)
+{
+ DPL::ScopedFree<char> sf(getcwd(NULL, 0));
+ std::string cwd(sf.Get());
+
+ Path path7 = Path("test") / "a///23/lol";
+ RUNNER_ASSERT(path7.Fullpath() == cwd + "/test/a/23/lol");
+ RUNNER_ASSERT(path7.Basename() == "lol");
+ RUNNER_ASSERT(path7.DirectoryName() == cwd + "/test/a/23");
+}
+
+/*
+Name: path_construction_8
+Description: constructs paths in many ways
+Expected: success full constrution
+*/
+RUNNER_TEST(path_construction_8)
+{
+ DPL::ScopedFree<char> sf(getcwd(NULL, 0));
+
+ Path path8 = Path("/test/bin/") / "123" / "dir1.dll";
+ RUNNER_ASSERT(path8.Fullpath() == "/test/bin/123/dir1.dll");
+ RUNNER_ASSERT(path8.Basename() == "dir1.dll");
+ RUNNER_ASSERT(path8.DirectoryName() == "/test/bin/123");
+}
+
+/*
+Name: path_construction_9
+Description: constructs paths in many ways
+Expected: success full constrution
+*/
+RUNNER_TEST(path_construction_9)
+{
+ DPL::ScopedFree<char> sf(getcwd(NULL, 0));
+
+ Path path9 = Path("/test/bin/file.txt//");
+ RUNNER_ASSERT(path9.Fullpath() == "/test/bin/file.txt");
+ RUNNER_ASSERT(path9.Basename() == "file.txt");
+ RUNNER_ASSERT(path9.DirectoryName() == "/test/bin");
+}
+
+/*
+Name: path_construction_10
+Description: constructs paths by appending
+Expected: success full constrution
+*/
+RUNNER_TEST(path_construction_10)
+{
+ Path path10 = Path("/test/");
+ path10 /= "one";
+ path10 /= std::string("two");
+ path10 /= DPL::String(L"three");
+ RUNNER_ASSERT(path10.Fullpath() == "/test/one/two/three");
+ RUNNER_ASSERT(path10.Basename() == "three");
+ RUNNER_ASSERT(path10.DirectoryName() == "/test/one/two");
+}
+
+/*
+Name: path_remove
+Description: tests removing paths
+Expected: successfull path remove
+*/
+RUNNER_TEST(path_remove_valid)
+{
+ DPL::ScopedDir sd(rootTest);
+
+ struct stat st;
+ Path path = Path(rootTest) / "touchDir";
+ RUNNER_ASSERT(!path.Exists());
+
+ MakeDir(path);
+ RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "Directory should be created");
+ RUNNER_ASSERT(path.Exists());
+
+ Remove(path);
+ RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) != 0, "Directory should not be created");
+ RUNNER_ASSERT(!path.Exists());
+
+ MakeEmptyFile(path);
+ RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "File should be created");
+ RUNNER_ASSERT(path.Exists());
+
+ Remove(path);
+ RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) != 0, "File should not be created");
+ RUNNER_ASSERT(!path.Exists());
+}
+
+/*
+Name: path_remove_invalid
+Description: tests removing invalid paths
+Expected: failure at path remove
+*/
+RUNNER_TEST(path_remove_invalid)
+{
+ DPL::ScopedDir sd(rootTest);
+
+ Path path = Path(rootTest) / "touchDir";
+
+ bool removedNotExisting = true;
+ Try
+ {
+ Remove(path);
+ }
+ Catch(Path::OperationFailed)
+ {
+ removedNotExisting = false;
+ }
+ RUNNER_ASSERT_MSG(!removedNotExisting, "Removing not existing file");
+}
+
+/*
+Name: path_rename
+Description: tests path renaming
+Expected: path is successfully renamed
+*/
+RUNNER_TEST(path_rename)
+{
+ DPL::ScopedDir sd(rootTest);
+
+ struct stat st;
+ Path path = Path(rootTest) / "touchDir";
+ Path dirpath = Path(rootTest) / "directory";
+ Path path2 = dirpath / "touchDir2";
+
+ MakeDir(dirpath);
+
+ MakeEmptyFile(path);
+ RUNNER_ASSERT_MSG(lstat(path.Fullpath().c_str(), &st) == 0, "File should be created");
+ RUNNER_ASSERT(path.Exists());
+ RUNNER_ASSERT(!path2.Exists());
+
+ Rename(path, path2);
+ RUNNER_ASSERT(!path.Exists());
+ RUNNER_ASSERT(path2.Exists());
+
+ Rename(path2, path);
+ RUNNER_ASSERT(path.Exists());
+ RUNNER_ASSERT(!path2.Exists());
+
+ //TODO: test for different devices
+}
+
+/*
+Name: path_rename_same
+Description: tests if renam does not brokens file if target location is equal to source location
+Expected: path is avaliable
+*/
+RUNNER_TEST(path_rename_same)
+{
+ DPL::ScopedDir sd(rootTest);
+
+ struct stat st;
+ Path path = Path(rootTest) / "touchDir";
+
+ MakeDir(path);
+ Rename(path, path);
+ RUNNER_ASSERT(path.Exists());
+}
+
+/*
+Name: path_iterate_not_directory
+Description: iterates not a directory
+Expected: success full constrution
+*/
+RUNNER_TEST(path_iterate_not_directory)
+{
+ DPL::ScopedDir sd(rootTest);
+
+ Path fileTest = Path(rootTest) / "file.txt";
+ MakeEmptyFile(fileTest);
+
+ bool passed = false;
+ Try
+ {
+ FOREACH(file, fileTest)
+ {
+
+ }
+ }
+ Catch(Path::NotDirectory)
+ {
+ passed = true;
+ }
+ RUNNER_ASSERT(passed);
+}
+
+/*
+Name: path_construction
+Description: constructs paths in many ways
+Expected: success full constrution
+*/
+RUNNER_TEST(path_iterate_empty_directory)
+{
+ DPL::ScopedDir sd(rootTest);
+
+ Path dirTest = Path(rootTest) / "directory";
+ MakeDir(dirTest);
+
+ bool passed = true;
+ Try
+ {
+ FOREACH(file, dirTest)
+ {
+ passed = false;
+ LogError("Directory should be empty");
+ }
+ }
+ Catch(Path::NotDirectory)
+ {
+ passed = false;
+ LogError("Directory should exists");
+ }
+ RUNNER_ASSERT(passed);
+}
+
+/*
+Name: path_construction
+Description: constructs paths in many ways
+Expected: success full constrution
+*/
+RUNNER_TEST(path_iterate_notempty_directory)
+{
+ DPL::ScopedDir sd(rootTest);
+
+ Path dirTest = Path(rootTest) / "directory";
+
+ Path path1 = Path(rootTest) / "directory" / "file1";
+ Path path2 = Path(rootTest) / "directory" / "file2";
+ Path path3 = Path(rootTest) / "directory" / "file3";
+
+ std::set<std::string> resultSet;
+ std::set<std::string> testSet;
+ testSet.insert(path1.Fullpath());
+ testSet.insert(path2.Fullpath());
+ testSet.insert(path3.Fullpath());
+
+ MakeDir(dirTest);
+ MakeEmptyFile(path1);
+ MakeEmptyFile(path2);
+ MakeEmptyFile(path3);
+
+ FOREACH(file, dirTest)
+ {
+ resultSet.insert(file->Fullpath());
+ }
+
+ RUNNER_ASSERT_MSG(testSet == resultSet, "Testing");
+}
+
+/*
+Name: path_construction
+Description: constructs paths in many ways
+Expected: success full constrution
+*/
+RUNNER_TEST(path_iterator_copy_constructor)
+{
+ DPL::ScopedDir sd(rootTest);
+
+ Path dirTest = Path(rootTest) / "directory";
+
+ Path path1 = Path(rootTest) / "directory" / "file1";
+ Path path2 = Path(rootTest) / "directory" / "file2";
+ Path path3 = Path(rootTest) / "directory" / "file3";
+
+ MakeDir(dirTest);
+ MakeEmptyFile(path1);
+ MakeEmptyFile(path2);
+ MakeEmptyFile(path3);
+
+ std::shared_ptr<Path::Iterator> iter1(new Path::Iterator((Path(rootTest) / "directory").Fullpath().c_str()));
+
+ //as it's input iterator it's guaranteed for one element to be iterate only once
+ (*iter1)++;
+ std::shared_ptr<Path::Iterator> iter2(new Path::Iterator( (*iter1)));
+ iter1.reset();
+ (*iter2)++;
+ ++(*iter2);
+ RUNNER_ASSERT_MSG(*iter2 == dirTest.end(), "Iterator is in broken state");
+ iter2.reset();
+}