You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

247 lines
7.2 KiB

#include <iostream>
#include <cctype>
#include <pEp/pEpEngine.h>
#include <pEp/message_api.h>
#include <pEp/keymanagement.h>
#include <pEp/identity_list.h>
#include <utility>
#include <pEp/utils.hh>
#include <pEp/pEpLog.hh>
#include <pEp/inspect.hh>
#include <type_traits>
//#include "../examples/libc99/libc99.h"
#include "../src/prototype.hh"
void test_getters(int* c_int_p, pEp::POD<int>& pint, int expected)
{
pEpLog("to_string(): " + pint.to_string());
// compare addresses
pEpLog("addresses == c_int_p");
assert(pint.c_data() == c_int_p);
assert(pint.data() == c_int_p);
// compare values
if (c_int_p != nullptr) {
pEpLog("operator int(): " + std::to_string(pint));
assert(pint == *c_int_p);
assert(pint == expected);
// will segfault with nullptr, and this is correct
pEpLog("data(): " + std::to_string(*pint.data()));
assert(*pint.data() == *c_int_p);
assert(*pint.data() == expected);
pEpLog("c_data(): " + std::to_string(*pint.c_data()));
assert(*pint.c_data() == *c_int_p);
assert(*pint.c_data() == expected);
}
}
void test_assign(int* c_int_p, pEp::POD<int>& pint)
{
{
pEpLogH2("assign operator");
int new_val = 23;
pint = new_val;
test_getters(c_int_p, pint, new_val);
}
{
pEpLogH2("raw c_str assign");
int new_val = 23;
*c_int_p = new_val;
test_getters(c_int_p, pint, new_val);
}
}
void test_getters(char** c_str_p, pEp::String& pstr, const std::string& expected)
{
pEpLog("to_string(): " + pstr.to_string());
// compare addresses
pEpLog("addresses == c_str_p");
assert(pstr.c_data() == *c_str_p);
assert(pstr.data() == c_str_p);
// compare values
if (*c_str_p != nullptr) {
pEpLog("operator std::string(): " + std::string(pstr));
assert(std::string(pstr) == std::string(*c_str_p));
assert(std::string(pstr) == expected);
// will segfault with nullptr, and this is correct
pEpLog("data(): " + std::string(*pstr.data()));
assert(std::string(*pstr.data()) == std::string(*c_str_p));
assert(std::string(*pstr.data()) == expected);
pEpLog("c_data(): " + std::string(pstr.c_data()));
assert(std::string(pstr.c_data()) == std::string(*c_str_p));
assert(std::string(pstr.c_data()) == expected);
} else {
std::string tmp{ pstr };
pEpLog("operator std::string(): " + tmp);
assert(tmp.empty());
}
}
void test_assign(char** c_str_p, pEp::String& pstr)
{
{
pEpLogH2("assign operator");
std::string new_val{ "assign operator" };
pstr = new_val;
test_getters(c_str_p, pstr, new_val);
}
{
pEpLogH2("raw c_str assign");
std::string new_val{ "raw c_str assign" };
free(*c_str_p);
*c_str_p = strdup(new_val.c_str());
test_getters(c_str_p, pstr, new_val);
}
}
int main()
{
// c-types are always POD
// we need to handle pointer types and value types differently
// pointer types need to be memory-managed (heap)
// value types are being copied around (stack)
static_assert(std::is_pod<int>::value && !std::is_pointer<int>::value, "not an integral");
static_assert(
std::is_pod<::Test_enum>::value && !std::is_pointer<::Test_enum>::value,
"not an integral");
static_assert(
std::is_pod<::Test_struct1>::value && !std::is_pointer<::Test_struct1>::value,
"not an integral");
// pEp::Utils::readKey();
pEp::Adapter::pEpLog::set_enabled(true);
// POD
if (1) {
// VALID USAGE
int init_val = 0;
// new pEp::POD on int
{
pEpLogH1("new pEp::POD on int");
int c_int = init_val;
pEp::POD<int> pint(&c_int);
test_getters(&c_int, pint, init_val);
test_assign(&c_int, pint);
}
// equality operator
{
pEpLogH1("equality operator");
int c_int1 = init_val;
int c_int2 = init_val;
pEp::POD<int> pint1(&c_int1);
pEp::POD<int> pint2(&c_int2);
assert(pint1 == pint2);
c_int2 = 23;
assert(pint1 != pint2);
}
}
// String
// pEp::String::log_enabled = false;
if (1) {
//TODO: Test non-owning mode
// INVALID USAGE
// char* c_str_u; // uninitialized == INVALID
// undefined behaviour, most likely "pointer being freed was not allocated"
// {
// char* c_str;
// pEp::String pstr(c_str);
// }
// char* c_str_s = "fdsfs"; // statically initialized == INVALID
// {
// char ca[4] = { 'p', 'E', 'p'};
// char* c_str = ca;
// pEp::String pstr(c_str);
// }
// VALID USAGE
// new pEp::String on char* pointing to NULL
{
pEpLogH1("new pEp::String on char* pointing to NULL");
char* c_str = NULL; // nullptr
pEp::String pstr(true, &c_str);
test_getters(&c_str, pstr, "");
test_assign(&c_str, pstr);
}
std::string init_val{ "initialized c string" };
// new pEp::String on already initalized char*
{
pEpLogH1("new pEp::String on already initalized char*");
char* c_str = strdup(init_val.c_str());
pEp::String pstr(true, &c_str);
test_getters(&c_str, pstr, init_val);
test_assign(&c_str, pstr);
}
// bind()
{
pEpLogH1("bind()");
pEp::String pstr{};
char* c_str = strdup(init_val.c_str());
//TODO: PITYASSERT_THROWS
pstr.bind(true, &c_str);
test_getters(&c_str, pstr, init_val);
test_assign(&c_str, pstr);
}
// equality operator
{
pEpLogH1("equality operator");
pEp::String pstr1{};
char* c_str1 = strdup(init_val.c_str());
char* c_str2 = strdup(init_val.c_str());
pstr1.bind(true, &c_str1);
pEp::String pstr2{ true, &c_str2 };
assert(pstr1 == pstr2);
pstr2 = "huhu";
assert(pstr1 != pstr2);
}
}
// Struct
if (1) {
// create an instance
if (1) {
pEp::TestStruct1 pstruct1{ true };
// pEp::TestStruct1 pstruct1(true, 23, TWO, "pEp");
pEpLog(pstruct1.c_int);
pEpLog(pstruct1.c_enum);
pEpLog(pstruct1.c_str);
::Test_struct1* c_struct1 = pstruct1;
pEpLog(c_struct1->c_int);
pEpLog(c_struct1->c_enum);
pEpLog(c_struct1->c_str);
pEpLog("DONE");
}
// wrap already existing instance
{
::Test_struct1* c_struct1 = ::new_test_struct(0, ONE, "pEp");
pEpLog(c_struct1->c_int);
pEpLog(c_struct1->c_enum);
pEpLog(c_struct1->c_str);
pEpLog("DONE");
pEp::TestStruct1 pstruct1(true, &c_struct1);
pEpLog(pstruct1.c_int);
pEpLog(pstruct1.c_enum);
pEpLog(pstruct1.c_str);
pEpLog("DONE");
}
}
}