Browse Source

added more tests, fixed some bugs

experiment/meta_header
Martchus 6 years ago
parent
commit
93582b4ac0
  1. 3
      .gitignore
  2. 4
      application/commandlineutils.h
  3. 5
      io/inifile.cpp
  4. 37
      io/path.cpp
  5. 2
      io/path.h
  6. 5
      misc/random.cpp
  7. 12
      testfiles/test.ini
  8. 84
      tests/iotests.cpp

3
.gitignore

@ -39,3 +39,6 @@ Makefile*
# documentation
/doc
# tests
testfiles/output.*

4
application/commandlineutils.h

@ -16,9 +16,9 @@ bool LIB_EXPORT confirmPrompt(const char *message, Response defaultResponse = Re
#ifdef PLATFORM_WINDOWS
void LIB_EXPORT startConsole();
#define CMD_UTILS_START_CONSOLE ::ApplicationUtilities::startConsole();
# define CMD_UTILS_START_CONSOLE ::ApplicationUtilities::startConsole();
#else
#define CMD_UTILS_START_CONSOLE
# define CMD_UTILS_START_CONSOLE
#endif
} // namespace ApplicationUtilities

5
io/inifile.cpp

@ -24,7 +24,10 @@ void IniFile::parse(std::istream &inputStream)
value.reserve(256);
// define actions for state machine
// 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) {
m_data.emplace_back(make_pair(scope, decltype(m_data)::value_type::second_type()));
}

37
io/path.cpp

@ -25,13 +25,14 @@
#endif
using namespace std;
using namespace IoUtilities;
using namespace ConversionUtilities;
namespace IoUtilities {
/*!
* \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 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.
*/
void IoUtilities::removeInvalidChars(string &path)
void removeInvalidChars(string &fileName)
{
size_t startPos = 0;
static const char invalidPathChars[] = {'\"', '<', '>', '?', '!', '*', '|', '/', ':', '\\', '\n'};
for(const char *i = invalidPathChars, *end = invalidPathChars + sizeof(invalidPathChars); i != end; ++i) {
startPos = path.find(*i);
startPos = fileName.find(*i);
while(startPos != string::npos) {
path.replace(startPos, 1, "");
startPos = path.find(*i, startPos);
fileName.replace(startPos, 1, string());
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.
* \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();
fstream pathConfigFile("path.config", ios_base::in);
@ -92,12 +93,12 @@ bool IoUtilities::settingsDirectory(string &result, string applicationDirectoryN
struct stat sb;
return (stat(result.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode));
#else
#ifdef PLATFORM_WINDOWS
# ifdef PLATFORM_WINDOWS
DWORD ftyp = GetFileAttributesA(result.c_str());
return (ftyp != INVALID_FILE_ATTRIBUTES) && (ftyp & FILE_ATTRIBUTE_DIRECTORY);
#else
#error Platform not supported.
#endif
# else
# error Platform not supported.
# endif
#endif
} else {
if(!applicationDirectoryName.empty()) {
@ -126,7 +127,7 @@ bool IoUtilities::settingsDirectory(string &result, string applicationDirectoryN
}
}
#else
#ifdef PLATFORM_WINDOWS
# ifdef PLATFORM_WINDOWS
if(char *appData = getenv("appdata")) {
result = appData;
if(!applicationDirectoryName.empty()) {
@ -149,10 +150,12 @@ bool IoUtilities::settingsDirectory(string &result, string applicationDirectoryN
} else {
return false;
}
#else
#error Platform not supported.
#endif
#endif
# else
# error Platform not supported.
# endif
#endif
}
return true;
}
}

2
io/path.h

@ -11,7 +11,7 @@
namespace IoUtilities {
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);
}

5
misc/random.cpp

@ -14,8 +14,7 @@ using namespace std;
* \brief Contains miscellaneous utility functions.
*/
namespace Utilities
{
namespace RandomUtilities {
//! @cond
const char letters[28] = "qwertzuiopasdfghjklyxcvbnm";
@ -26,6 +25,7 @@ const char symbols[24] = "!\"$%&/()=?'#*+~-_><.:,;";
/*!
* \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)
{
@ -114,6 +114,7 @@ void generateRandomCharacterSequence(char *result, unsigned int length, std::fun
/*!
* \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)
{

12
testfiles/test.ini

@ -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

84
tests/iotests.cpp

@ -1,6 +1,9 @@
#include "../io/binaryreader.h"
#include "../io/binarywriter.h"
#include "../io/bitreader.h"
#include "../io/path.h"
#include "../io/inifile.h"
#include "../io/copy.h"
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestFixture.h>
@ -24,6 +27,9 @@ class IoTests : public TestFixture
CPPUNIT_TEST(testBinaryReader);
CPPUNIT_TEST(testBinaryWriter);
CPPUNIT_TEST(testBitReader);
CPPUNIT_TEST(testPathUtilities);
CPPUNIT_TEST(testIniFile);
CPPUNIT_TEST(testCopy);
CPPUNIT_TEST_SUITE_END();
public:
@ -34,6 +40,9 @@ public:
void testBinaryReader();
void testBinaryWriter();
void testBitReader();
void testPathUtilities();
void testIniFile();
void testCopy();
};
CPPUNIT_TEST_SUITE_REGISTRATION(IoTests);
@ -185,3 +194,78 @@ void IoTests::testBitReader()
CPPUNIT_ASSERT(reader.readBits<byte>(8) == 0x44);
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…
Cancel
Save