added more tests, fixed some bugs
This commit is contained in:
parent
503e4cf3c7
commit
93582b4ac0
|
@ -39,3 +39,6 @@ Makefile*
|
||||||
|
|
||||||
# documentation
|
# documentation
|
||||||
/doc
|
/doc
|
||||||
|
|
||||||
|
# tests
|
||||||
|
testfiles/output.*
|
||||||
|
|
|
@ -24,7 +24,10 @@ void IniFile::parse(std::istream &inputStream)
|
||||||
value.reserve(256);
|
value.reserve(256);
|
||||||
// define actions for state machine
|
// define actions for state machine
|
||||||
// called when key/value pair is complete
|
// called when key/value pair is complete
|
||||||
const auto finishKeyValue = [&scope, &key, &value, &whitespace, this] {
|
const auto finishKeyValue = [&state, &scope, &key, &value, &whitespace, this] {
|
||||||
|
if(key.empty() && value.empty() && state != Value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(m_data.empty() || m_data.back().first != scope) {
|
if(m_data.empty() || m_data.back().first != scope) {
|
||||||
m_data.emplace_back(make_pair(scope, decltype(m_data)::value_type::second_type()));
|
m_data.emplace_back(make_pair(scope, decltype(m_data)::value_type::second_type()));
|
||||||
}
|
}
|
||||||
|
|
19
io/path.cpp
19
io/path.cpp
|
@ -25,13 +25,14 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace IoUtilities;
|
|
||||||
using namespace ConversionUtilities;
|
using namespace ConversionUtilities;
|
||||||
|
|
||||||
|
namespace IoUtilities {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the file name and extension of the specified \a path string.
|
* \brief Returns the file name and extension of the specified \a path string.
|
||||||
*/
|
*/
|
||||||
string IoUtilities::fileName(const string &path)
|
string fileName(const string &path)
|
||||||
{
|
{
|
||||||
size_t lastSlash = path.rfind('/');
|
size_t lastSlash = path.rfind('/');
|
||||||
size_t lastBackSlash = path.rfind('\\');
|
size_t lastBackSlash = path.rfind('\\');
|
||||||
|
@ -48,19 +49,19 @@ string IoUtilities::fileName(const string &path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Removes invalid characters from the specified \a path string.
|
* \brief Removes invalid characters from the specified \a fileName.
|
||||||
*
|
*
|
||||||
* The characters <, >, ?, !, *, |, /, :, \ and new lines are considered as invalid.
|
* The characters <, >, ?, !, *, |, /, :, \ and new lines are considered as invalid.
|
||||||
*/
|
*/
|
||||||
void IoUtilities::removeInvalidChars(string &path)
|
void removeInvalidChars(string &fileName)
|
||||||
{
|
{
|
||||||
size_t startPos = 0;
|
size_t startPos = 0;
|
||||||
static const char invalidPathChars[] = {'\"', '<', '>', '?', '!', '*', '|', '/', ':', '\\', '\n'};
|
static const char invalidPathChars[] = {'\"', '<', '>', '?', '!', '*', '|', '/', ':', '\\', '\n'};
|
||||||
for(const char *i = invalidPathChars, *end = invalidPathChars + sizeof(invalidPathChars); i != end; ++i) {
|
for(const char *i = invalidPathChars, *end = invalidPathChars + sizeof(invalidPathChars); i != end; ++i) {
|
||||||
startPos = path.find(*i);
|
startPos = fileName.find(*i);
|
||||||
while(startPos != string::npos) {
|
while(startPos != string::npos) {
|
||||||
path.replace(startPos, 1, "");
|
fileName.replace(startPos, 1, string());
|
||||||
startPos = path.find(*i, startPos);
|
startPos = fileName.find(*i, startPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +73,7 @@ void IoUtilities::removeInvalidChars(string &path)
|
||||||
* \param createApplicationDirectory Indicates wheter the application subdirectory should be created if not present.
|
* \param createApplicationDirectory Indicates wheter the application subdirectory should be created if not present.
|
||||||
* \returns Returns if a settings directory could be located.
|
* \returns Returns if a settings directory could be located.
|
||||||
*/
|
*/
|
||||||
bool IoUtilities::settingsDirectory(string &result, string applicationDirectoryName, bool createApplicationDirectory)
|
bool settingsDirectory(string &result, string applicationDirectoryName, bool createApplicationDirectory)
|
||||||
{
|
{
|
||||||
result.clear();
|
result.clear();
|
||||||
fstream pathConfigFile("path.config", ios_base::in);
|
fstream pathConfigFile("path.config", ios_base::in);
|
||||||
|
@ -156,3 +157,5 @@ bool IoUtilities::settingsDirectory(string &result, string applicationDirectoryN
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
namespace IoUtilities {
|
namespace IoUtilities {
|
||||||
|
|
||||||
LIB_EXPORT std::string fileName(const std::string &path);
|
LIB_EXPORT std::string fileName(const std::string &path);
|
||||||
LIB_EXPORT void removeInvalidChars(std::string &path);
|
LIB_EXPORT void removeInvalidChars(std::string &fileName);
|
||||||
LIB_EXPORT bool settingsDirectory(std::string &result, std::string applicationDirectoryName = std::string(), bool createApplicationDirectory = false);
|
LIB_EXPORT bool settingsDirectory(std::string &result, std::string applicationDirectoryName = std::string(), bool createApplicationDirectory = false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,7 @@ using namespace std;
|
||||||
* \brief Contains miscellaneous utility functions.
|
* \brief Contains miscellaneous utility functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Utilities
|
namespace RandomUtilities {
|
||||||
{
|
|
||||||
|
|
||||||
//! @cond
|
//! @cond
|
||||||
const char letters[28] = "qwertzuiopasdfghjklyxcvbnm";
|
const char letters[28] = "qwertzuiopasdfghjklyxcvbnm";
|
||||||
|
@ -26,6 +25,7 @@ const char symbols[24] = "!\"$%&/()=?'#*+~-_><.:,;";
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Generates a random character sequence using the given \a randomizer.
|
* \brief Generates a random character sequence using the given \a randomizer.
|
||||||
|
* \remarks Might be removed because not used anymore.
|
||||||
*/
|
*/
|
||||||
void generateRandomCharacterSequence(char *result, unsigned int length, std::function<int ()> randomizer, int highestRandomNumber, bool useSmallLetters, bool useCapitalLetters, bool useNumbers, bool useSymbols, bool useAtLeastOneOfEachCategory)
|
void generateRandomCharacterSequence(char *result, unsigned int length, std::function<int ()> randomizer, int highestRandomNumber, bool useSmallLetters, bool useCapitalLetters, bool useNumbers, bool useSymbols, bool useAtLeastOneOfEachCategory)
|
||||||
{
|
{
|
||||||
|
@ -114,6 +114,7 @@ void generateRandomCharacterSequence(char *result, unsigned int length, std::fun
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Generates a random character sequence using std::rand().
|
* \brief Generates a random character sequence using std::rand().
|
||||||
|
* \remarks Might be removed because not used anymore.
|
||||||
*/
|
*/
|
||||||
void generateRandomCharacterSequence(char *result, unsigned int length, bool useSmallLetters, bool useCapitalLetters, bool useNumbers, bool useSymbols, bool useAtLeastOneOfEachCategory)
|
void generateRandomCharacterSequence(char *result, unsigned int length, bool useSmallLetters, bool useCapitalLetters, bool useNumbers, bool useSymbols, bool useAtLeastOneOfEachCategory)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
# file for testing INI parser
|
||||||
|
key0=value 0
|
||||||
|
|
||||||
|
[scope 1]
|
||||||
|
key1=value 1 # comment
|
||||||
|
key2=value=2
|
||||||
|
key3=value 3
|
||||||
|
|
||||||
|
[scope 2]
|
||||||
|
key4=value 4
|
||||||
|
#key5=value 5
|
||||||
|
key6=value 6
|
|
@ -1,6 +1,9 @@
|
||||||
#include "../io/binaryreader.h"
|
#include "../io/binaryreader.h"
|
||||||
#include "../io/binarywriter.h"
|
#include "../io/binarywriter.h"
|
||||||
#include "../io/bitreader.h"
|
#include "../io/bitreader.h"
|
||||||
|
#include "../io/path.h"
|
||||||
|
#include "../io/inifile.h"
|
||||||
|
#include "../io/copy.h"
|
||||||
|
|
||||||
#include <cppunit/extensions/HelperMacros.h>
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
#include <cppunit/TestFixture.h>
|
#include <cppunit/TestFixture.h>
|
||||||
|
@ -24,6 +27,9 @@ class IoTests : public TestFixture
|
||||||
CPPUNIT_TEST(testBinaryReader);
|
CPPUNIT_TEST(testBinaryReader);
|
||||||
CPPUNIT_TEST(testBinaryWriter);
|
CPPUNIT_TEST(testBinaryWriter);
|
||||||
CPPUNIT_TEST(testBitReader);
|
CPPUNIT_TEST(testBitReader);
|
||||||
|
CPPUNIT_TEST(testPathUtilities);
|
||||||
|
CPPUNIT_TEST(testIniFile);
|
||||||
|
CPPUNIT_TEST(testCopy);
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -34,6 +40,9 @@ public:
|
||||||
void testBinaryReader();
|
void testBinaryReader();
|
||||||
void testBinaryWriter();
|
void testBinaryWriter();
|
||||||
void testBitReader();
|
void testBitReader();
|
||||||
|
void testPathUtilities();
|
||||||
|
void testIniFile();
|
||||||
|
void testCopy();
|
||||||
};
|
};
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION(IoTests);
|
CPPUNIT_TEST_SUITE_REGISTRATION(IoTests);
|
||||||
|
@ -185,3 +194,78 @@ void IoTests::testBitReader()
|
||||||
CPPUNIT_ASSERT(reader.readBits<byte>(8) == 0x44);
|
CPPUNIT_ASSERT(reader.readBits<byte>(8) == 0x44);
|
||||||
CPPUNIT_ASSERT_THROW(reader.readBit(), std::ios_base::failure);
|
CPPUNIT_ASSERT_THROW(reader.readBit(), std::ios_base::failure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Tests fileName() and removeInvalidChars().
|
||||||
|
*/
|
||||||
|
void IoTests::testPathUtilities()
|
||||||
|
{
|
||||||
|
CPPUNIT_ASSERT(fileName("/usr/lib/libc++utilities.so") == "libc++utilities.so");
|
||||||
|
string invalidPath("lib/c++uti*lities.so?");
|
||||||
|
removeInvalidChars(invalidPath);
|
||||||
|
CPPUNIT_ASSERT(invalidPath == "libc++utilities.so");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Tests IniFile.
|
||||||
|
*/
|
||||||
|
void IoTests::testIniFile()
|
||||||
|
{
|
||||||
|
// prepare reading test file
|
||||||
|
fstream inputFile;
|
||||||
|
inputFile.exceptions(ios_base::failbit | ios_base::badbit);
|
||||||
|
inputFile.open(UnitTests::testFilesPath + "/test.ini", ios_base::in);
|
||||||
|
|
||||||
|
IniFile ini;
|
||||||
|
ini.parse(inputFile);
|
||||||
|
const auto globalScope = ini.data().at(0);
|
||||||
|
const auto scope1 = ini.data().at(1);
|
||||||
|
const auto scope2 = ini.data().at(2);
|
||||||
|
CPPUNIT_ASSERT(globalScope.first.empty());
|
||||||
|
CPPUNIT_ASSERT(globalScope.second.find("key0") != globalScope.second.cend());
|
||||||
|
CPPUNIT_ASSERT(globalScope.second.find("key0")->second == "value 0");
|
||||||
|
CPPUNIT_ASSERT(globalScope.second.find("key1") == globalScope.second.cend());
|
||||||
|
CPPUNIT_ASSERT(scope1.first == "scope 1");
|
||||||
|
CPPUNIT_ASSERT(scope1.second.find("key1") != scope1.second.cend());
|
||||||
|
CPPUNIT_ASSERT(scope1.second.find("key1")->second == "value 1");
|
||||||
|
CPPUNIT_ASSERT(scope1.second.find("key2") != scope1.second.cend());
|
||||||
|
CPPUNIT_ASSERT(scope1.second.find("key2")->second == "value=2");
|
||||||
|
CPPUNIT_ASSERT(scope2.first == "scope 2");
|
||||||
|
CPPUNIT_ASSERT(scope2.second.find("key5") == scope2.second.cend());
|
||||||
|
|
||||||
|
// write values to another file
|
||||||
|
fstream outputFile;
|
||||||
|
outputFile.exceptions(ios_base::failbit | ios_base::badbit);
|
||||||
|
outputFile.open(UnitTests::testFilesPath + "/output.ini", ios_base::out | ios_base::trunc);
|
||||||
|
ini.make(outputFile);
|
||||||
|
|
||||||
|
// parse written values (again)
|
||||||
|
outputFile.close();
|
||||||
|
outputFile.open(UnitTests::testFilesPath + "/output.ini", ios_base::in);
|
||||||
|
IniFile ini2;
|
||||||
|
ini2.parse(outputFile);
|
||||||
|
CPPUNIT_ASSERT(ini.data() == ini2.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Tests CopyHelper.
|
||||||
|
*/
|
||||||
|
void IoTests::testCopy()
|
||||||
|
{
|
||||||
|
// prepare streams
|
||||||
|
fstream testFile;
|
||||||
|
testFile.open(UnitTests::testFilesPath + "/some_data", ios_base::in | ios_base::binary);
|
||||||
|
testFile.exceptions(ios_base::failbit | ios_base::badbit);
|
||||||
|
stringstream outputStream(ios_base::in | ios_base::out | ios_base::binary);
|
||||||
|
outputStream.exceptions(ios_base::failbit | ios_base::badbit);
|
||||||
|
|
||||||
|
// copy
|
||||||
|
CopyHelper<13> copyHelper;
|
||||||
|
copyHelper.copy(testFile, outputStream, 50);
|
||||||
|
|
||||||
|
// test
|
||||||
|
testFile.seekg(0);
|
||||||
|
for(byte i = 0; i < 50; ++i) {
|
||||||
|
CPPUNIT_ASSERT(testFile.get() == outputStream.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue