2017-10-25 18:25:34 +02:00
|
|
|
#include "./structs.h"
|
|
|
|
#include "./helper.h"
|
2017-10-18 23:07:17 +02:00
|
|
|
|
2017-10-25 18:25:34 +02:00
|
|
|
#include "../codefactory.h"
|
2017-10-24 01:00:40 +02:00
|
|
|
|
2017-10-18 23:07:17 +02:00
|
|
|
#include "resources/config.h"
|
|
|
|
|
|
|
|
#include <c++utilities/conversion/stringconversion.h>
|
|
|
|
#include <c++utilities/io/misc.h>
|
|
|
|
#include <c++utilities/tests/testutils.h>
|
|
|
|
|
|
|
|
#include <cppunit/TestFixture.h>
|
|
|
|
#include <cppunit/extensions/HelperMacros.h>
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
using namespace CPPUNIT_NS;
|
|
|
|
using namespace IoUtilities;
|
|
|
|
using namespace TestUtilities;
|
2017-10-21 00:32:42 +02:00
|
|
|
using namespace ConversionUtilities;
|
2017-10-25 16:47:14 +02:00
|
|
|
|
2017-10-21 00:32:42 +02:00
|
|
|
/*!
|
|
|
|
* \brief The OverallTests class tests the overall functionality of the code generator (CLI and generator itself).
|
|
|
|
*/
|
2017-10-18 23:07:17 +02:00
|
|
|
class OverallTests : public TestFixture {
|
|
|
|
CPPUNIT_TEST_SUITE(OverallTests);
|
2017-10-21 00:32:42 +02:00
|
|
|
CPPUNIT_TEST(testGeneratorItself);
|
2017-10-18 23:07:17 +02:00
|
|
|
CPPUNIT_TEST(testCLI);
|
2017-10-24 01:00:40 +02:00
|
|
|
CPPUNIT_TEST(testIncludingGeneratedHeader);
|
2017-10-25 16:47:14 +02:00
|
|
|
CPPUNIT_TEST(testSingleInheritence);
|
|
|
|
CPPUNIT_TEST(testMultipleInheritence);
|
2017-10-18 23:07:17 +02:00
|
|
|
CPPUNIT_TEST_SUITE_END();
|
|
|
|
|
|
|
|
public:
|
|
|
|
void setUp();
|
|
|
|
void tearDown();
|
|
|
|
|
2017-10-21 00:32:42 +02:00
|
|
|
void testGeneratorItself();
|
2017-10-18 23:07:17 +02:00
|
|
|
void testCLI();
|
2017-10-24 01:00:40 +02:00
|
|
|
void testIncludingGeneratedHeader();
|
2017-10-25 16:47:14 +02:00
|
|
|
void testSingleInheritence();
|
|
|
|
void testMultipleInheritence();
|
2017-10-18 23:07:17 +02:00
|
|
|
|
|
|
|
private:
|
2017-10-21 00:32:42 +02:00
|
|
|
vector<string> m_expectedCode;
|
2017-10-18 23:07:17 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
CPPUNIT_TEST_SUITE_REGISTRATION(OverallTests);
|
|
|
|
|
|
|
|
void OverallTests::setUp()
|
|
|
|
{
|
2017-10-21 00:32:42 +02:00
|
|
|
m_expectedCode = toArrayOfLines(readFile(testFilePath("some_structs_json_serialization.h"), 1024));
|
2017-10-18 23:07:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void OverallTests::tearDown()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-10-24 01:00:40 +02:00
|
|
|
/*!
|
|
|
|
* \brief Tests whether the generator works by using it directly.
|
|
|
|
*/
|
2017-10-21 00:32:42 +02:00
|
|
|
void OverallTests::testGeneratorItself()
|
2017-10-18 23:07:17 +02:00
|
|
|
{
|
|
|
|
const string inputFilePath(testFilePath("some_structs.h"));
|
2017-10-21 00:32:42 +02:00
|
|
|
const vector<const char *> inputFiles{ inputFilePath.data() };
|
2017-10-24 01:00:40 +02:00
|
|
|
const vector<const char *> clangOptions{};
|
2017-10-21 00:32:42 +02:00
|
|
|
|
2017-10-18 23:07:17 +02:00
|
|
|
stringstream buffer;
|
2017-10-24 01:00:40 +02:00
|
|
|
CodeFactory factory(TestApplication::appPath(), inputFiles, clangOptions, buffer);
|
|
|
|
factory.addGenerator<JSONSerializationCodeGenerator>();
|
2017-10-21 00:32:42 +02:00
|
|
|
CPPUNIT_ASSERT(factory.readAST());
|
|
|
|
CPPUNIT_ASSERT(factory.generate());
|
|
|
|
assertEqualityLinewise(m_expectedCode, toArrayOfLines(buffer.str()));
|
2017-10-18 23:07:17 +02:00
|
|
|
}
|
|
|
|
|
2017-10-24 01:00:40 +02:00
|
|
|
/*!
|
|
|
|
* \brief Test the generator via CLI.
|
|
|
|
* \remarks Only available under UNIX (like) systems so far, because TESTUTILS_ASSERT_EXEC has not been implemented
|
|
|
|
* for other platforms.
|
|
|
|
*/
|
2017-10-18 23:07:17 +02:00
|
|
|
void OverallTests::testCLI()
|
|
|
|
{
|
|
|
|
#ifdef PLATFORM_UNIX
|
|
|
|
string stdout, stderr;
|
2017-10-21 00:32:42 +02:00
|
|
|
|
|
|
|
const string inputFilePath(testFilePath("some_structs.h"));
|
2017-10-18 23:07:17 +02:00
|
|
|
const char *const args1[] = { PROJECT_NAME, "-i", inputFilePath.data(), nullptr };
|
|
|
|
TESTUTILS_ASSERT_EXEC(args1);
|
2017-10-21 00:32:42 +02:00
|
|
|
assertEqualityLinewise(m_expectedCode, toArrayOfLines(stdout));
|
2017-10-18 23:07:17 +02:00
|
|
|
#endif
|
|
|
|
}
|
2017-10-24 01:00:40 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Tests whether the generated reflection code actually works.
|
|
|
|
*/
|
|
|
|
void OverallTests::testIncludingGeneratedHeader()
|
|
|
|
{
|
|
|
|
TestStruct test;
|
|
|
|
test.someInt = 42;
|
|
|
|
test.someString = "the answer";
|
|
|
|
test.yetAnotherString = "but what was the question";
|
|
|
|
const string expectedJSON("{\"someInt\":42,\"someString\":\"the answer\",\"yetAnotherString\":\"but what was the question\"}");
|
|
|
|
|
|
|
|
// test serialization
|
|
|
|
CPPUNIT_ASSERT_EQUAL(expectedJSON, string(test.toJson().GetString()));
|
|
|
|
|
|
|
|
// test deserialization
|
|
|
|
const TestStruct parsedTest(TestStruct::fromJson(expectedJSON));
|
|
|
|
CPPUNIT_ASSERT_EQUAL(test.someInt, parsedTest.someInt);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(test.someString, parsedTest.someString);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(test.yetAnotherString, parsedTest.yetAnotherString);
|
|
|
|
}
|
|
|
|
|
2017-10-25 16:47:14 +02:00
|
|
|
/*!
|
|
|
|
* \brief Like testIncludingGeneratedHeader() but also tests single inheritence.
|
|
|
|
*/
|
|
|
|
void OverallTests::testSingleInheritence()
|
|
|
|
{
|
|
|
|
DerivedTestStruct test;
|
|
|
|
test.someInt = 42;
|
|
|
|
test.someString = "the answer";
|
|
|
|
test.yetAnotherString = "but what was the question";
|
|
|
|
test.someBool = false;
|
|
|
|
const string expectedJSONForBase("{\"someInt\":42,\"someString\":\"the answer\",\"yetAnotherString\":\"but what was the question\"}");
|
|
|
|
const string expectedJSONForDerived(
|
|
|
|
"{\"someInt\":42,\"someString\":\"the answer\",\"yetAnotherString\":\"but what was the question\",\"someBool\":false}");
|
|
|
|
|
|
|
|
// test serialization
|
|
|
|
CPPUNIT_ASSERT_EQUAL(expectedJSONForBase, string(static_cast<const JSONSerializable<TestStruct> &>(test).toJson().GetString()));
|
|
|
|
CPPUNIT_ASSERT_EQUAL(expectedJSONForDerived, string(static_cast<const JSONSerializable<DerivedTestStruct> &>(test).toJson().GetString()));
|
|
|
|
|
|
|
|
// test deserialization
|
|
|
|
const DerivedTestStruct parsedTest(JSONSerializable<DerivedTestStruct>::fromJson(expectedJSONForDerived));
|
|
|
|
CPPUNIT_ASSERT_EQUAL(test.someInt, parsedTest.someInt);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(test.someString, parsedTest.someString);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(test.yetAnotherString, parsedTest.yetAnotherString);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(test.someBool, parsedTest.someBool);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Like testIncludingGeneratedHeader() but also tests multiple inheritence.
|
|
|
|
*/
|
|
|
|
void OverallTests::testMultipleInheritence()
|
|
|
|
{
|
|
|
|
MultipleDerivedTestStruct test;
|
|
|
|
test.someInt = 42;
|
|
|
|
test.someString = "the answer";
|
|
|
|
test.yetAnotherString = "but what was the question";
|
|
|
|
test.someBool = false;
|
|
|
|
test.arrayOfStrings = { "array", "of", "strings" };
|
|
|
|
const string expectedJSONForDerived("{\"someInt\":42,\"someString\":\"the answer\",\"yetAnotherString\":\"but what was the "
|
|
|
|
"question\",\"arrayOfStrings\":[\"array\",\"of\",\"strings\"],\"someBool\":false}");
|
|
|
|
|
|
|
|
// test serialization
|
|
|
|
CPPUNIT_ASSERT_EQUAL(expectedJSONForDerived, string(static_cast<const JSONSerializable<MultipleDerivedTestStruct> &>(test).toJson().GetString()));
|
|
|
|
|
|
|
|
// test deserialization
|
|
|
|
const MultipleDerivedTestStruct parsedTest(JSONSerializable<MultipleDerivedTestStruct>::fromJson(expectedJSONForDerived));
|
|
|
|
CPPUNIT_ASSERT_EQUAL(test.someInt, parsedTest.someInt);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(test.someString, parsedTest.someString);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(test.yetAnotherString, parsedTest.yetAnotherString);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(test.someBool, parsedTest.someBool);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(test.arrayOfStrings, parsedTest.arrayOfStrings);
|
|
|
|
}
|
|
|
|
|
2017-10-25 18:25:34 +02:00
|
|
|
// include file required for reflection of TestStruct and other structs defined in structs.h
|
|
|
|
// NOTE: * generation of this header is triggered using the CMake function add_reflection_generator_invocation()
|
|
|
|
// * the include must happen in exactly one translation unit of the project at a point where the structs are defined
|
|
|
|
#include "reflection/structs.h"
|
2017-10-25 17:32:03 +02:00
|
|
|
|
2017-10-25 18:25:34 +02:00
|
|
|
// this file should also be generated via add_reflection_generator_invocation() and hence includeable
|
|
|
|
// it is included to test the "empty" case when a unit doesn't contain relevant classes
|
2017-10-25 17:32:03 +02:00
|
|
|
#include "reflection/cppunit.h"
|