From 486b99b39d21a7b2f30b8c786171ed6477b79f41 Mon Sep 17 00:00:00 2001 From: Michal Kaptur Date: Mon, 14 May 2018 21:26:26 +0200 Subject: [PATCH] Add some unit tests to Tools Clean up and test 3 methods from Tools: - humanReadableFileSize - isHex - isBase64 --- src/core/Tools.cpp | 35 ++++++++++++----------- src/core/Tools.h | 2 +- tests/CMakeLists.txt | 3 ++ tests/TestKeys.cpp | 1 - tests/TestModified.cpp | 1 - tests/TestTools.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++ tests/TestTools.h | 32 +++++++++++++++++++++ 7 files changed, 120 insertions(+), 19 deletions(-) create mode 100644 tests/TestTools.cpp create mode 100644 tests/TestTools.h diff --git a/src/core/Tools.cpp b/src/core/Tools.cpp index 5f51fa47d..458d42988 100644 --- a/src/core/Tools.cpp +++ b/src/core/Tools.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -56,8 +57,9 @@ namespace Tools { - QString humanReadableFileSize(qint64 bytes) + QString humanReadableFileSize(qint64 bytes, quint32 precision) { + constexpr auto kibibyte = 1024; double size = bytes; QStringList units = QStringList() << "B" @@ -67,12 +69,12 @@ namespace Tools int i = 0; int maxI = units.size() - 1; - while ((size >= 1024) && (i < maxI)) { - size /= 1024; + while ((size >= kibibyte) && (i < maxI)) { + size /= kibibyte; i++; } - return QString("%1 %2").arg(QLocale().toString(size, 'f', 2), units.at(i)); + return QString("%1 %2").arg(QLocale().toString(size, 'f', precision), units.at(i)); } bool hasChild(const QObject* parent, const QObject* child) @@ -147,8 +149,8 @@ namespace Tools bool isHex(const QByteArray& ba) { - for (char c : ba) { - if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) { + for (const unsigned char c : ba) { + if (!std::isxdigit(c)) { return false; } } @@ -158,8 +160,8 @@ namespace Tools bool isBase64(const QByteArray& ba) { - QRegExp regexp( - "^(?:[a-z0-9+/]{4})*(?:[a-z0-9+/]{3}=|[a-z0-9+/]{2}==)?$", Qt::CaseInsensitive, QRegExp::RegExp2); + constexpr auto pattern = R"(^(?:[a-z0-9+]{4})*(?:[a-z0-9+]{3}=|[a-z0-9+]{2}==)?$)"; + QRegExp regexp(pattern, Qt::CaseInsensitive, QRegExp::RegExp2); QString base64 = QString::fromLatin1(ba.constData(), ba.size()); @@ -318,14 +320,15 @@ namespace Tools } // Set discretionary access control list - bSuccess = ERROR_SUCCESS == SetSecurityInfo(GetCurrentProcess(), // object handle - SE_KERNEL_OBJECT, // type of object - DACL_SECURITY_INFORMATION, // change only the objects DACL - nullptr, - nullptr, // do not change owner or group - pACL, // DACL specified - nullptr // do not change SACL - ); + bSuccess = ERROR_SUCCESS + == SetSecurityInfo(GetCurrentProcess(), // object handle + SE_KERNEL_OBJECT, // type of object + DACL_SECURITY_INFORMATION, // change only the objects DACL + nullptr, + nullptr, // do not change owner or group + pACL, // DACL specified + nullptr // do not change SACL + ); Cleanup: diff --git a/src/core/Tools.h b/src/core/Tools.h index b11760079..9fd497995 100644 --- a/src/core/Tools.h +++ b/src/core/Tools.h @@ -32,7 +32,7 @@ class QIODevice; namespace Tools { - QString humanReadableFileSize(qint64 bytes); + QString humanReadableFileSize(qint64 bytes, quint32 precision = 2); bool hasChild(const QObject* parent, const QObject* child); bool readFromDevice(QIODevice* device, QByteArray& data, int size = 16384); bool readAllFromDevice(QIODevice* device, QByteArray& data); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index df5c37f83..261c9627e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -190,6 +190,9 @@ add_unit_test(NAME testykchallengeresponsekey add_unit_test(NAME testdatabase SOURCES TestDatabase.cpp LIBS ${TEST_LIBRARIES}) +add_unit_test(NAME testtools SOURCES TestTools.cpp + LIBS ${TEST_LIBRARIES}) + if(WITH_GUI_TESTS) add_subdirectory(gui) endif(WITH_GUI_TESTS) diff --git a/tests/TestKeys.cpp b/tests/TestKeys.cpp index e5cc75c2c..f04aabcb5 100644 --- a/tests/TestKeys.cpp +++ b/tests/TestKeys.cpp @@ -24,7 +24,6 @@ #include "config-keepassx-tests.h" #include "core/Metadata.h" -#include "core/Tools.h" #include "crypto/Crypto.h" #include "crypto/CryptoHash.h" #include "crypto/kdf/AesKdf.h" diff --git a/tests/TestModified.cpp b/tests/TestModified.cpp index 0a9f0cfa2..60ea68e5f 100644 --- a/tests/TestModified.cpp +++ b/tests/TestModified.cpp @@ -23,7 +23,6 @@ #include "core/Database.h" #include "core/Group.h" #include "core/Metadata.h" -#include "core/Tools.h" #include "crypto/Crypto.h" QTEST_GUILESS_MAIN(TestModified) diff --git a/tests/TestTools.cpp b/tests/TestTools.cpp new file mode 100644 index 000000000..c3acd3c6d --- /dev/null +++ b/tests/TestTools.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2017 KeePassXC Team + * + * 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 or (at your option) + * version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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, see . + */ + +#include "TestTools.h" + +#include +#include + +QTEST_GUILESS_MAIN(TestTools) + +namespace +{ + QString createDecimal(QString wholes, QString fractions, QString unit) + { + return wholes + QLocale().decimalPoint() + fractions + " " + unit; + } +} + +void TestTools::testHumanReadableFileSize() +{ + constexpr auto kibibyte = 1024u; + using namespace Tools; + + QCOMPARE(createDecimal("1", "00", "B"), humanReadableFileSize(1)); + QCOMPARE(createDecimal("1", "00", "KiB"), humanReadableFileSize(kibibyte)); + QCOMPARE(createDecimal("1", "00", "MiB"), humanReadableFileSize(kibibyte * kibibyte)); + QCOMPARE(createDecimal("1", "00", "GiB"), humanReadableFileSize(kibibyte * kibibyte * kibibyte)); + + QCOMPARE(QString("100 B"), humanReadableFileSize(100, 0)); + QCOMPARE(createDecimal("1", "10", "KiB"), humanReadableFileSize(kibibyte + 100)); + QCOMPARE(createDecimal("1", "001", "KiB"), humanReadableFileSize(kibibyte + 1, 3)); + QCOMPARE(createDecimal("15", "00", "KiB"), humanReadableFileSize(kibibyte * 15)); +} + +void TestTools::testIsHex() +{ + QVERIFY(Tools::isHex("0123456789abcdefABCDEF")); + QVERIFY(not Tools::isHex(QByteArray("0xnothex"))); +} + +void TestTools::testIsBase64() +{ + QVERIFY(Tools::isBase64(QByteArray("1234"))); + QVERIFY(Tools::isBase64(QByteArray("123="))); + QVERIFY(Tools::isBase64(QByteArray("12=="))); + QVERIFY(Tools::isBase64(QByteArray("abcd9876MN=="))); + QVERIFY(Tools::isBase64(QByteArray("abcd9876DEFGhijkMNO="))); + QVERIFY(not Tools::isBase64(QByteArray("abcd123=="))); + QVERIFY(not Tools::isBase64(QByteArray("abc_"))); + QVERIFY(not Tools::isBase64(QByteArray("123"))); +} diff --git a/tests/TestTools.h b/tests/TestTools.h new file mode 100644 index 000000000..56d354eca --- /dev/null +++ b/tests/TestTools.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2017 KeePassXC Team + * + * 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 or (at your option) + * version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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, see . + */ + +#ifndef KEEPASSX_TESTTOOLS_H +#define KEEPASSX_TESTTOOLS_H + +#include "core/Tools.h" + +class TestTools : public QObject +{ + Q_OBJECT +private slots: + void testHumanReadableFileSize(); + void testIsHex(); + void testIsBase64(); +}; + +#endif // KEEPASSX_TESTTOOLS_H