Skip to content
This repository has been archived by the owner on Sep 4, 2021. It is now read-only.

Commit

Permalink
Merge pull request #1 from nemomobile/staging
Browse files Browse the repository at this point in the history
A bit more functionality and new soversion
  • Loading branch information
Denis Zalevskiy committed Oct 15, 2014
2 parents d70f9fe + 47e977f commit c00907f
Show file tree
Hide file tree
Showing 10 changed files with 229 additions and 28 deletions.
23 changes: 12 additions & 11 deletions include/qtaround/error.hpp
Expand Up @@ -14,26 +14,27 @@

namespace qtaround { namespace error {

template <typename T>
QString dump(T && t)
{
QString s;
QDebug d(&s);
d << t;
return s;
}

class Error : public std::exception
{
public:
Error(QVariantMap const &from) : m(from) {}
virtual ~Error() noexcept(true) {}
virtual const char* what() const noexcept(true)
{
QString s;
QDebug(&s) << m;
return s.toUtf8();
}
virtual const char* what() const noexcept(true);

QVariantMap m;
mutable QString s;
};

static inline QDebug operator << (QDebug dst, error::Error const &src)
{
dst << src.m;
return dst;
}
QDebug operator << (QDebug dst, error::Error const &src);

static inline void raise(QVariantMap const &m)
{
Expand Down
33 changes: 33 additions & 0 deletions include/qtaround/os.hpp
Expand Up @@ -17,6 +17,10 @@
#include <QString>
#include <QVariant>
#include <QDateTime>
#include <QLockFile>

#include <memory>


namespace qtaround { namespace os {

Expand Down Expand Up @@ -235,6 +239,35 @@ static inline QString getTemp(A &&...args)
return os::path::join(getTemp(), std::forward<A>(args)...);
}

typedef std::unique_ptr<QLockFile> LockFileHandle;
class FileLock
{
public:
FileLock(LockFileHandle &&from) : lock_(std::move(from)) {}
//lock_ is movable only
private:
LockFileHandle lock_;
};

template <typename OnLocked>
LockFileHandle tryLock(LockFileHandle &&locker, OnLocked fn)
{
if (locker) {
if (locker->tryLock()) {
fn(FileLock(std::move(locker)));
return nullptr;
}
}
return std::move(locker);
}

template <typename OnLocked>
LockFileHandle tryLock(QString const &fileName, OnLocked fn)
{
LockFileHandle h{new QLockFile(fileName)};
return tryLock(std::move(h), fn);
}

}}

#endif // _CUTES_OS_HPP_
21 changes: 17 additions & 4 deletions include/qtaround/util.hpp
Expand Up @@ -319,32 +319,45 @@ QVariant visit(visitor_type visitor, QVariant const &src, QVariant const &ctx);

#define UNIQUE_PTR(T) std::unique_ptr<T, void(*)(T*)>

template <typename T>
typename UNIQUE_PTR(T)::deleter_type get_qobject_deleter()
{
return [](T *p) { p->deleteLater(); };
}

template <typename T, typename ... Args>
UNIQUE_PTR(T) make_qobject_unique(Args &&...args)
{
return UNIQUE_PTR(T)
(new T(std::forward<Args>(args)...)
, [](T *p) { p->deleteLater(); });
, get_qobject_deleter<T>());
}

template <typename T, typename ... Args>
std::shared_ptr<T> make_qobject_shared(Args &&...args)
{
return std::shared_ptr<T>
(new T(std::forward<Args>(args)...)
, [](T *p) { p->deleteLater(); });
, get_qobject_deleter<T>());
}

template <typename T>
std::shared_ptr<T> qobject_shared(T *p)
{
return std::shared_ptr<T>(p, [](T *p) { p->deleteLater(); });
return std::shared_ptr<T>(p, get_qobject_deleter<T>());
}

template <typename T>
std::shared_ptr<T> qobject_shared(UNIQUE_PTR(T) p)
{
return std::shared_ptr<T>(p.release(), [](T *p) { p->deleteLater(); });
return std::shared_ptr<T>(p.release(), get_qobject_deleter<T>());
}

template <typename T>
UNIQUE_PTR(T) qobject_box(T &&v)
{
std::unique_ptr<T> p(new T(std::move(v)));
return p;
}

#endif // _CUTES_UTIL_HPP_
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Expand Up @@ -6,7 +6,7 @@ add_library(qtaround SHARED
qt5_use_modules(qtaround Core)
target_link_libraries(qtaround ${COR_LIBRARIES})
set_target_properties(qtaround PROPERTIES
SOVERSION 0
SOVERSION 1
VERSION ${VERSION}
)
install(TARGETS qtaround DESTINATION ${DST_LIB})
Expand Down
6 changes: 6 additions & 0 deletions src/os.cpp
Expand Up @@ -11,6 +11,11 @@
#include <qtaround/debug.hpp>
#include <QDebug>

#include <sys/stat.h>
#include <fcntl.h>
#include <cor/util.hpp>
#include <tuple>

namespace qtaround { namespace os {

namespace path {
Expand Down Expand Up @@ -384,4 +389,5 @@ QString mkTemp(QVariantMap &&options)
return res.trimmed();
}


}} // os
21 changes: 19 additions & 2 deletions src/util.cpp
@@ -1,7 +1,6 @@
/**
* @file util.cpp
* @brief Misc. helpful utilities
* @author Denis Zalevskiy <denis.zalevskiy@jolla.com>
* @copyright (C) 2014 Jolla Ltd.
* @par License: LGPL 2.1 http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
*/
Expand All @@ -12,7 +11,25 @@
#include <QString>
#include <QMap>

namespace qtaround { namespace util {
namespace qtaround {

namespace error {
const char* Error::what() const noexcept(true)
{
if (s.isEmpty())
s = dump(m);
return s.toUtf8();
}

QDebug operator << (QDebug dst, error::Error const &src)
{
dst << src.m;
return dst;
}

}

namespace util {

namespace {

Expand Down
5 changes: 3 additions & 2 deletions tests/CMakeLists.txt
Expand Up @@ -4,7 +4,7 @@ include_directories(${TUT_INCLUDES})
find_package(Qt5Core REQUIRED)
set(CMAKE_AUTOMOC TRUE)

set(UNIT_TESTS os dbus)
set(UNIT_TESTS os dbus misc)
set(TESTS_DIR /opt/tests/qtaround)

MACRO(UNIT_TEST _name)
Expand Down Expand Up @@ -33,4 +33,5 @@ target_link_libraries(test_dbus

configure_file(tests.xml.in tests.xml @ONLY)
FILE(GLOB SH_FILES *.sh)
install(PROGRAMS tests.xml ${SH_FILES} DESTINATION ${TESTS_DIR})
install(PROGRAMS ${SH_FILES} DESTINATION ${TESTS_DIR})
install(FILES tests.xml DESTINATION ${TESTS_DIR})
131 changes: 131 additions & 0 deletions tests/misc.cpp
@@ -0,0 +1,131 @@
#include <qtaround/util.hpp>
#include <qtaround/os.hpp>
#include <tut/tut.hpp>
#include "tests_common.hpp"
#include <qtaround/util.hpp>

#include <QDebug>
#include <QVariant>

namespace os = qtaround::os;
namespace error = qtaround::error;
namespace util = qtaround::util;

namespace tut
{

struct misc_test
{
virtual ~misc_test()
{
}
};

typedef test_group<misc_test> tf;
typedef tf::object object;
tf vault_misc_test("misc");

enum test_ids {
tid_visit = 1
, tid_zip
, tid_parsebytes
, tid_error
};

template<> template<>
void object::test<tid_visit>()
{
QVariantMap src = {
{"b1", true},
{"m1", map({{"s1", "Str 1"}})},
{"l1", list({false, "List str"})}
};
QStringList expected = {"///"
, "QString//QString/b1/bool/true"
, "QString//QString/l1"
, "QString//QString/m1"
, "QString/l1/int/0/bool/false"
, "QString/l1/int/1/QString/List str"
, "QString/m1/QString/s1/QString/Str 1"};

QStringList dst;
auto fn = [&dst](QVariant const &ctx, QVariant const &key
, QVariant const &data) {
auto k = str(key);
QStringList v;
v << ctx.typeName() << str(ctx) << key.typeName() << k;
if (!(hasType(data, QMetaType::QVariantMap)
|| hasType(data, QMetaType::QVariantList)))
v << data.typeName() << str(data);
dst << v.join("/");
return k;
};
util::visit(fn, src, QVariant());
dst.sort();
expected.sort();
ensure_eq("Visited items", dst, expected);
}

template<> template<>
void object::test<tid_zip>()
{
QStringList l1, l2;
l1 << "A";
l2 << "a";
auto res = util::zip(l1, l2);
ensure_eq("Single item", res.size(), 1);
l1 << "B";
res = util::zip(l1, l2);
ensure_eq("2 items, 2nd empty", res.size(), 2);
l2 << "b";
res = util::zip(l1, l2);
ensure_eq("2 items", res.size(), 2);
l2 << "c";
res = util::zip(l1, l2);
ensure_eq("2 items, w/o 3rd", res.size(), 2);

}

template<> template<>
void object::test<tid_parsebytes>()
{
double res = util::parseBytes("10");
ensure_eq("plain bytes", res, 10);
res = util::parseBytes("10K");
ensure_eq("10K", res, 1024 * 10);
res = util::parseBytes("20Kb");
ensure_eq("10Kb", res, 1024 * 20);
res = util::parseBytes("30kib");
ensure_eq("30Kb", res, 1024 * 30);
res = util::parseBytes(" 40 kb ");
ensure_eq("40K", res, 1024 * 40);

ensure_throws<error::Error>("10 k b", &util::parseBytes, " 10 k b ", "b", 1024);

res = util::parseBytes("50mb");
ensure_eq("50mb", res, 1024 * 1024 * 50);

res = util::parseBytes("60Mib", "b", 1000);
ensure_eq("60Mib", res, 1000 * 1000 * 60);

res = util::parseBytes("70mb", "mb");
ensure_eq("70mb", res, 70);

res = util::parseBytes("1024kb", "mb");
ensure_eq("1mb", res, 1);

res = util::parseBytes("1024kb", "GB");
ensure_eq("1024kb=xGb", res, 1. / 1024.);
}

template<> template<>
void object::test<tid_error>()
{
try {
error::raise({{"a", 1}, {"b", 2}});
} catch (error::Error const &e) {
ensure_ne(AT, S_(e.what()), "");
}
}

}
6 changes: 6 additions & 0 deletions tests/os.cpp
Expand Up @@ -6,6 +6,7 @@

namespace os = qtaround::os;
namespace error = qtaround::error;
using error::dump;

namespace {

Expand Down Expand Up @@ -331,7 +332,12 @@ void object::test<tid_mountpoint>()
{
auto home = os::home();
auto mp = os::mountpoint(home);
ensure_ne("There should be some mountpoint", mp.size(), 0);
ensure(AT, os::path::isDescendent(home, mp));
auto s = os::stat(home, {{"fields", "m"}});
auto mp2 = s["mount_point"];
if (mp != "?")
ensure_eq("Should be the same mountpoint if it is not ?", mp2, mp);
}

template<> template<>
Expand Down
9 changes: 1 addition & 8 deletions tests/tests_common.hpp
Expand Up @@ -46,14 +46,7 @@ QStringList strings(QString const &s, A &&...args)
return QStringList(s) + strings(std::forward<A>(args)...);
}

template <typename T>
QString dump(T && t)
{
QString s;
QDebug d(&s);
d << t;
return s;
}
#define S_(...) strings(__VA_ARGS__).join(' ').toStdString()

}

Expand Down

0 comments on commit c00907f

Please sign in to comment.