added more test cases

This commit is contained in:
Martchus 2016-01-27 01:01:43 +01:00
parent 1d8177ba41
commit 80a4ce1790
6 changed files with 355 additions and 16 deletions

View File

@ -53,6 +53,7 @@ set(TEST_SRC_FILES
tests/cppunit.cpp
tests/conversiontests.cpp
tests/iotests.cpp
tests/chronotests.cpp
)
# meta data
@ -120,12 +121,14 @@ set_target_properties(${META_PROJECT_NAME} PROPERTIES
# add check target
if(NOT TARGET check)
set(CMAKE_CTEST_COMMAND ctest -V)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
enable_testing()
endif()
add_executable(${META_PROJECT_NAME}_tests EXCLUDE_FROM_ALL ${TEST_HEADER_FILES} ${TEST_SRC_FILES})
target_link_libraries(${META_PROJECT_NAME}_tests c++utilities cppunit)
set_target_properties(${META_PROJECT_NAME}_tests PROPERTIES CXX_STANDARD 11)
add_test(NAME ${META_PROJECT_NAME}_tests COMMAND ${META_PROJECT_NAME}_tests)
add_test(NAME ${META_PROJECT_NAME}_cppunit COMMAND ${META_PROJECT_NAME}_tests -p "${CMAKE_CURRENT_SOURCE_DIR}/testfiles")
add_dependencies(check ${META_PROJECT_NAME}_tests)
# add install target

BIN
testfiles/some_data Normal file

Binary file not shown.

101
tests/chronotests.cpp Normal file
View File

@ -0,0 +1,101 @@
#include "../chrono/datetime.h"
#include "../chrono/timespan.h"
#include "../chrono/period.h"
#include "../conversion/conversionexception.h"
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestFixture.h>
#include <iostream>
using namespace std;
using namespace ConversionUtilities;
using namespace ChronoUtilities;
using namespace CPPUNIT_NS;
class ChronoTests : public TestFixture
{
CPPUNIT_TEST_SUITE(ChronoTests);
CPPUNIT_TEST(testDateTime);
CPPUNIT_TEST(testTimeSpan);
CPPUNIT_TEST(testOperators);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
void tearDown() {}
void testDateTime();
void testTimeSpan();
void testOperators();
};
CPPUNIT_TEST_SUITE_REGISTRATION(ChronoTests);
/*!
* \brief Tests most important DateTime features.
*/
void ChronoTests::testDateTime()
{
// test year(), month(), ...
auto test1 = DateTime::fromDateAndTime(2012, 2, 29, 15, 34, 20, 33.0);
CPPUNIT_ASSERT(test1.year() == 2012);
CPPUNIT_ASSERT(test1.month() == 2);
CPPUNIT_ASSERT(test1.day() == 29);
CPPUNIT_ASSERT(test1.minute() == 34);
CPPUNIT_ASSERT(test1.second() == 20);
CPPUNIT_ASSERT(test1.millisecond() == 33);
CPPUNIT_ASSERT(test1.dayOfWeek() == DayOfWeek::Wednesday);
CPPUNIT_ASSERT(test1.dayOfYear() == (31 + 29));
CPPUNIT_ASSERT(test1.isLeapYear());
CPPUNIT_ASSERT(test1.toString(DateTimeOutputFormat::DateTimeAndShortWeekday) == "Wed 2012-02-29 15:34:20.33");
// test fromTimeStamp()
auto test2 = DateTime::fromTimeStampGmt(1453840331);
CPPUNIT_ASSERT(test2.toString(DateTimeOutputFormat::DateTimeAndShortWeekday) == "Tue 2016-01-26 20:32:11");
// test whether ConversionException() is thrown when invalid values are specified
CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2013, 2, 29, 15, 34, 20, 33), ConversionException);
CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 2, 29, 15, 61, 20, 33), ConversionException);
CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 4, 31, 15, 0, 20, 33), ConversionException);
CPPUNIT_ASSERT_THROW(DateTime::fromDateAndTime(2012, 3, 31, 15, 0, 61, 33), ConversionException);
}
/*!
* \brief Tests most important TimeSpan features.
*/
void ChronoTests::testTimeSpan()
{
// test fromString(...), this should also test all other from...() methods and + operator
auto test1 = TimeSpan::fromString("2:34:53:2.5");
// test days(), hours(), ...
CPPUNIT_ASSERT(test1.days() == 3);
CPPUNIT_ASSERT(test1.hours() == 10);
CPPUNIT_ASSERT(test1.minutes() == 53);
CPPUNIT_ASSERT(test1.seconds() == 2);
CPPUNIT_ASSERT(test1.milliseconds() == 500);
CPPUNIT_ASSERT(test1.totalDays() > 3.0 && test1.totalDays() < 4.0);
CPPUNIT_ASSERT(test1.totalHours() > (2 * 24 + 34) && test1.totalHours() < (2 * 24 + 35));
CPPUNIT_ASSERT(test1.totalMinutes() > (2 * 24 * 60 + 34 * 60 + 53) && test1.totalHours() < (2 * 24 * 60 + 34 * 60 + 54));
CPPUNIT_ASSERT(test1.toString(TimeSpanOutputFormat::WithMeasures, false) == "3 d 10 h 53 min 2 s 500 ms");
// test whether ConversionException() is thrown when invalid values are specified
CPPUNIT_ASSERT_THROW(TimeSpan::fromString("2:34a:53:32.5"), ConversionException);
}
/*!
* \brief Tests operators of DateTime / TimeSpan.
*/
void ChronoTests::testOperators()
{
auto dateTime = DateTime::fromDateAndTime(1999, 1, 5, 4, 16);
CPPUNIT_ASSERT((dateTime + TimeSpan::fromDays(2)).day() == 7);
CPPUNIT_ASSERT((dateTime + TimeSpan::fromHours(24)).day() == 6);
CPPUNIT_ASSERT((dateTime + TimeSpan::fromHours(24) + TimeSpan::fromHours(-1)).hour() == 3);
CPPUNIT_ASSERT((dateTime + TimeSpan::fromHours(24) - TimeSpan::fromMinutes(-1)).minute() == 17);
dateTime += TimeSpan::fromDays(365);
CPPUNIT_ASSERT(dateTime.year() == 2000);
CPPUNIT_ASSERT(dateTime.day() == 5);
CPPUNIT_ASSERT(Period(dateTime, dateTime + TimeSpan::fromDays(62)).months() == 2);
}

View File

@ -1,4 +1,5 @@
#include "../conversion/binaryconversion.h"
#include "../conversion/stringconversion.h"
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestFixture.h>
@ -6,6 +7,7 @@
#include <random>
#include <sstream>
#include <functional>
#include <initializer_list>
using namespace std;
using namespace ConversionUtilities;
@ -17,6 +19,7 @@ class ConversionTests : public TestFixture
CPPUNIT_TEST_SUITE(ConversionTests);
CPPUNIT_TEST(testEndianness);
CPPUNIT_TEST(testBinaryConversions);
CPPUNIT_TEST(testStringConversions);
CPPUNIT_TEST_SUITE_END();
public:
@ -27,6 +30,7 @@ public:
void testEndianness();
void testBinaryConversions();
void testStringConversions();
private:
template<typename intType>
@ -69,8 +73,7 @@ void ConversionTests::testConversion(const char *message, function<void (intType
stringstream msg;
msg << message << '(' << hex << '0' << 'x' << random << ')';
vice(random, m_buff);
const intType result = versa(m_buff);
CPPUNIT_ASSERT_MESSAGE(msg.str(), result == random);
CPPUNIT_ASSERT_MESSAGE(msg.str(), versa(m_buff) == random);
}
#define TEST_TYPE(endianness, function) \
@ -104,20 +107,19 @@ void ConversionTests::testConversion(const char *message, function<void (intType
)
/*!
* \brief Tests some binary conversions.
* \brief Tests most important binary conversions.
*
* Tests toUInt16(), ... toUInt64(), toInt16(), ... toInt64() and
* the inverse getBytes() functions.
* the inverse getBytes() functions with random numbers.
*/
void ConversionTests::testBinaryConversions()
{
for(byte b = 0; b < 100; ++b) {
// test to...() / getBytes() with random numbers
for(byte b = 1; b < 100; ++b) {
TEST_BE_CONVERSION(toUInt16);
TEST_CUSTOM_CONVERSION(getBytes24, toUInt24, BE, 0, 0xFFFFFF);
TEST_BE_CONVERSION(toUInt32);
TEST_BE_CONVERSION(toUInt64);
TEST_LE_CONVERSION(toUInt16);
TEST_CUSTOM_CONVERSION(getBytes24, toUInt24, LE, 0, 0xFFFFFF);
TEST_LE_CONVERSION(toUInt32);
TEST_LE_CONVERSION(toUInt64);
TEST_BE_CONVERSION(toInt16);
@ -126,6 +128,68 @@ void ConversionTests::testBinaryConversions()
TEST_LE_CONVERSION(toInt16);
TEST_LE_CONVERSION(toInt32);
TEST_LE_CONVERSION(toInt64);
TEST_CUSTOM_CONVERSION(getBytes24, toUInt24, BE, 0, 0xFFFFFF);
TEST_CUSTOM_CONVERSION(getBytes24, toUInt24, LE, 0, 0xFFFFFF);
}
}
/*!
* \brief Tests most important string conversions.
*/
void ConversionTests::testStringConversions()
{
// test stringToNumber() / numberToString() with random numbers
uniform_int_distribution<int64> randomDistSigned(numeric_limits<int64>::min());
uniform_int_distribution<uint64> randomDistUnsigned(0);
for(byte b = 1; b < 100; ++b) {
auto signedRandom = randomDistSigned(m_randomEngine);
auto unsignedRandom = randomDistUnsigned(m_randomEngine);
for(const auto base : initializer_list<byte>{2, 8, 10, 16}) {
auto resultString = stringToNumber<uint64, string>(numberToString<uint64, string>(unsignedRandom, base), base);
auto resultWideString = stringToNumber<uint64, wstring>(numberToString<uint64, wstring>(unsignedRandom, base), base);
CPPUNIT_ASSERT(resultString == unsignedRandom);
CPPUNIT_ASSERT(resultWideString == unsignedRandom);
}
for(const auto base : initializer_list<byte>{10}) {
auto resultString = stringToNumber<int64, string>(numberToString<int64, string>(signedRandom, base), base);
auto resultWideString = stringToNumber<int64, wstring>(numberToString<int64, wstring>(signedRandom, base), base);
CPPUNIT_ASSERT(resultString == signedRandom);
CPPUNIT_ASSERT(resultWideString == signedRandom);
}
}
// test interpretIntegerAsString()
CPPUNIT_ASSERT(interpretIntegerAsString<uint32>(0x54455354) == "TEST");
// test splitString() / joinStrings()
auto splitJoinTest = joinStrings(splitString<vector<string> >(",a,,ab,ABC,s", ",", EmptyPartsTreat::Keep), " ", false, "(", ")");
CPPUNIT_ASSERT(splitJoinTest == "() (a) () (ab) (ABC) (s)");
splitJoinTest = joinStrings(splitString<vector<string> >(",a,,ab,ABC,s", ",", EmptyPartsTreat::Keep), " ", true, "(", ")");
CPPUNIT_ASSERT(splitJoinTest == "(a) (ab) (ABC) (s)");
splitJoinTest = joinStrings(splitString<vector<string> >(",a,,ab,ABC,s", ",", EmptyPartsTreat::Omit), " ", false, "(", ")");
CPPUNIT_ASSERT(splitJoinTest == "(a) (ab) (ABC) (s)");
splitJoinTest = joinStrings(splitString<vector<string> >(",a,,ab,ABC,s", ",", EmptyPartsTreat::Merge), " ", false, "(", ")");
CPPUNIT_ASSERT(splitJoinTest == "(a,ab) (ABC) (s)");
// test findAndReplace()
string findReplaceTest("findAndReplace()");
findAndReplace<string>(findReplaceTest, "And", "Or");
CPPUNIT_ASSERT(findReplaceTest == "findOrReplace()");
// test startsWith()
CPPUNIT_ASSERT(!startsWith<string>(findReplaceTest, "findAnd"));
CPPUNIT_ASSERT(startsWith<string>(findReplaceTest, "findOr"));
// test encodeBase64() / decodeBase64() with random data
uniform_int_distribution<byte> randomDistChar;
byte originalBase64Data[4047];
for(byte &c : originalBase64Data) {
c = randomDistChar(m_randomEngine);
}
const auto encodedBase64Data = encodeBase64(originalBase64Data, sizeof(originalBase64Data));
auto decodedBase64Data = decodeBase64(encodedBase64Data.data(), encodedBase64Data.size());
CPPUNIT_ASSERT(decodedBase64Data.second == sizeof(originalBase64Data));
for(unsigned int i = 0; i < sizeof(originalBase64Data); ++i) {
CPPUNIT_ASSERT(decodedBase64Data.first[i] == originalBase64Data[i]);
}
}

View File

@ -1,13 +1,49 @@
#include "../application/argumentparser.h"
#include "../application/failure.h"
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <iostream>
using namespace std;
using namespace ApplicationUtilities;
using namespace CPPUNIT_NS;
int main(int , char **)
{
TextUi::TestRunner runner;
TestFactoryRegistry &registry = TestFactoryRegistry::getRegistry();
runner.addTest(registry.makeTest());
return !runner.run(string(), false);
namespace UnitTests {
string testFilesPath("tests");
}
int main(int argc, char **argv)
{
// setup argument parser
ArgumentParser parser;
HelpArgument helpArg(parser);
Argument testFilesPathArg("test-files-path", "p", "specifies the path to the directory with test files");
testFilesPathArg.setRequiredValueCount(1);
testFilesPathArg.setValueNames({"path"});
testFilesPathArg.setCombinable(true);
parser.setMainArguments({&testFilesPathArg, &helpArg});
try {
// parse arguments
parser.parseArgs(argc, argv);
if(testFilesPathArg.isPresent()) {
UnitTests::testFilesPath = testFilesPathArg.values().front();
}
cerr << "Direcoty for test files: " << UnitTests::testFilesPath << endl;
// run tests
TextUi::TestRunner runner;
TestFactoryRegistry &registry = TestFactoryRegistry::getRegistry();
runner.addTest(registry.makeTest());
return !runner.run(string(), false);
} catch(const Failure &failure) {
cerr << "Invalid arguments specified: " << failure.what() << endl;
return -1;
}
}

View File

@ -1,25 +1,46 @@
#include "../io/binaryreader.h"
#include "../io/binarywriter.h"
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestFixture.h>
#include <fstream>
#include <sstream>
using namespace std;
using namespace IoUtilities;
using namespace CPPUNIT_NS;
namespace UnitTests {
extern string testFilesPath;
}
class IoTests : public TestFixture
{
CPPUNIT_TEST_SUITE(IoTests);
CPPUNIT_TEST(testFailure);
CPPUNIT_TEST(testBinaryReader);
CPPUNIT_TEST(testBinaryWriter);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
void tearDown() {}
void setUp();
void tearDown();
void testFailure();
void testBinaryReader();
void testBinaryWriter();
};
CPPUNIT_TEST_SUITE_REGISTRATION(IoTests);
void IoTests::setUp()
{}
void IoTests::tearDown()
{}
/*!
* \brief Tests for GCC Bug 66145.
* \sa https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145
@ -30,3 +51,117 @@ void IoTests::testFailure()
stream.exceptions(ios_base::failbit | ios_base::badbit);
CPPUNIT_ASSERT_THROW(stream.open("path/to/file/which/does/not/exist", ios_base::in), ios_base::failure);
}
/*!
* \brief Tests the most important methods of the BinaryReader.
*/
void IoTests::testBinaryReader()
{
// read test file
fstream testFile;
testFile.open(UnitTests::testFilesPath + "/some_data", ios_base::in | ios_base::binary);
BinaryReader reader(&testFile);
CPPUNIT_ASSERT(reader.readUInt16LE() == 0x0102u);
CPPUNIT_ASSERT(reader.readUInt16BE() == 0x0102u);
CPPUNIT_ASSERT(reader.readUInt24LE() == 0x010203u);
CPPUNIT_ASSERT(reader.readUInt24BE() == 0x010203u);
CPPUNIT_ASSERT(reader.readUInt32LE() == 0x01020304u);
CPPUNIT_ASSERT(reader.readUInt32BE() == 0x01020304u);
CPPUNIT_ASSERT(reader.readUInt40LE() == 0x0102030405u);
CPPUNIT_ASSERT(reader.readUInt40BE() == 0x0102030405u);
CPPUNIT_ASSERT(reader.readUInt56LE() == 0x01020304050607u);
CPPUNIT_ASSERT(reader.readUInt56BE() == 0x01020304050607u);
CPPUNIT_ASSERT(reader.readUInt64LE() == 0x0102030405060708u);
CPPUNIT_ASSERT(reader.readUInt64BE() == 0x0102030405060708u);
testFile.seekg(0);
CPPUNIT_ASSERT(reader.readInt16LE() == 0x0102);
CPPUNIT_ASSERT(reader.readInt16BE() == 0x0102);
CPPUNIT_ASSERT(reader.readInt24LE() == 0x010203);
CPPUNIT_ASSERT(reader.readInt24BE() == 0x010203);
CPPUNIT_ASSERT(reader.readInt32LE() == 0x01020304);
CPPUNIT_ASSERT(reader.readInt32BE() == 0x01020304);
CPPUNIT_ASSERT(reader.readInt40LE() == 0x0102030405);
CPPUNIT_ASSERT(reader.readInt40BE() == 0x0102030405);
CPPUNIT_ASSERT(reader.readInt56LE() == 0x01020304050607);
CPPUNIT_ASSERT(reader.readInt56BE() == 0x01020304050607);
CPPUNIT_ASSERT(reader.readInt64LE() == 0x0102030405060708);
CPPUNIT_ASSERT(reader.readInt64BE() == 0x0102030405060708);
CPPUNIT_ASSERT(reader.readFloat32LE() == 1.125);
CPPUNIT_ASSERT(reader.readFloat64LE() == 1.625);
CPPUNIT_ASSERT(reader.readFloat32BE() == 1.125);
CPPUNIT_ASSERT(reader.readFloat64BE() == 1.625);
CPPUNIT_ASSERT(reader.readBool() == false);
CPPUNIT_ASSERT(reader.readBool() == true);
CPPUNIT_ASSERT(reader.readString(3) == "abc");
CPPUNIT_ASSERT(reader.readLengthPrefixedString() == "ABC");
CPPUNIT_ASSERT(reader.readTerminatedString() == "def");
}
/*!
* \brief Tests the most important methods of the BinaryWriter.
*/
void IoTests::testBinaryWriter()
{
// prepare reading expected data
fstream testFile;
testFile.open(UnitTests::testFilesPath + "/some_data", ios_base::in | ios_base::binary);
// prepare output stream
stringstream outputStream(ios_base::in | ios_base::out | ios_base::binary);
outputStream.exceptions(ios_base::failbit | ios_base::badbit);
char testData[95];
outputStream.rdbuf()->pubsetbuf(testData, sizeof(testData));
// write test data
BinaryWriter writer(&outputStream);
writer.writeUInt16LE(0x0102u);
writer.writeUInt16BE(0x0102u);
writer.writeUInt24LE(0x010203u);
writer.writeUInt24BE(0x010203u);
writer.writeUInt32LE(0x01020304u);
writer.writeUInt32BE(0x01020304u);
writer.writeUInt40LE(0x0102030405u);
writer.writeUInt40BE(0x0102030405u);
writer.writeUInt56LE(0x01020304050607u);
writer.writeUInt56BE(0x01020304050607u);
writer.writeUInt64LE(0x0102030405060708u);
writer.writeUInt64BE(0x0102030405060708u);
// test written values
for(char c : testData) {
CPPUNIT_ASSERT(c == static_cast<char>(testFile.get()));
if(testFile.tellg() >= 58) {
break;
}
}
testFile.seekg(0);
outputStream.seekp(0);
// write more test data
writer.writeInt16LE(0x0102);
writer.writeInt16BE(0x0102);
writer.writeInt24LE(0x010203);
writer.writeInt24BE(0x010203);
writer.writeInt32LE(0x01020304);
writer.writeInt32BE(0x01020304);
writer.writeInt40LE(0x0102030405);
writer.writeInt40BE(0x0102030405);
writer.writeInt56LE(0x01020304050607);
writer.writeInt56BE(0x01020304050607);
writer.writeInt64LE(0x0102030405060708);
writer.writeInt64BE(0x0102030405060708);
writer.writeFloat32LE(1.125);
writer.writeFloat64LE(1.625);
writer.writeFloat32BE(1.125);
writer.writeFloat64BE(1.625);
writer.writeBool(false);
writer.writeBool(true);
writer.writeString("abc");
writer.writeLengthPrefixedString("ABC");
writer.writeTerminatedString("def");
// test written values
for(char c : testData) {
CPPUNIT_ASSERT(c == static_cast<char>(testFile.get()));
}
}