Skip to content

Commit

Permalink
test
Browse files Browse the repository at this point in the history
  • Loading branch information
TinyTinni committed Nov 16, 2024
1 parent ca44fd8 commit 8399b59
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 106 deletions.
21 changes: 17 additions & 4 deletions tests/proptests/generators/vdf_multiobject_generator.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#include "vdf_multiobject_generator.hpp"

namespace tyti::vdf
{
bool operator==(const tyti::vdf::multikey_object &rhs,
const tyti::vdf::multikey_object &lhs)
template <typename charT>
bool equal_impl(const tyti::vdf::basic_multikey_object<charT> &rhs,
const tyti::vdf::basic_multikey_object<charT> &lhs)
{
if (rhs.name != lhs.name)
return false;
Expand Down Expand Up @@ -34,6 +33,20 @@ bool operator==(const tyti::vdf::multikey_object &rhs,

return true;
}
namespace tyti::vdf
{

bool operator==(const tyti::vdf::multikey_object &rhs,
const tyti::vdf::multikey_object &lhs)
{
return equal_impl(rhs, lhs);
}
bool operator==(const tyti::vdf::wmultikey_object &rhs,
const tyti::vdf::wmultikey_object &lhs)
{
return equal_impl(rhs, lhs);
}

} // namespace tyti::vdf

namespace rc::detail
Expand Down
12 changes: 7 additions & 5 deletions tests/proptests/generators/vdf_multiobject_generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@ namespace tyti::vdf
{
bool operator==(const tyti::vdf::multikey_object &rhs,
const tyti::vdf::multikey_object &lhs);
bool operator==(const tyti::vdf::wmultikey_object &rhs,
const tyti::vdf::wmultikey_object &lhs);
} // namespace tyti::vdf

namespace rc
{

template <> struct Arbitrary<tyti::vdf::multikey_object>
template <typename charT>
struct Arbitrary<tyti::vdf::basic_multikey_object<charT>>
{
static Gen<tyti::vdf::multikey_object> arbitrary()
static Gen<tyti::vdf::basic_multikey_object<charT>> arbitrary()
{
using tyti::vdf::multikey_object;
return gen::build<multikey_object>(gen::set(&multikey_object::name),
gen::set(&multikey_object::attribs));
using obj = tyti::vdf::basic_multikey_object<charT>;
return gen::build<obj>(gen::set(&obj::name), gen::set(&obj::attribs));
}
};
} // namespace rc
Expand Down
20 changes: 17 additions & 3 deletions tests/proptests/generators/vdf_object_generator.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "vdf_object_generator.hpp"

namespace tyti::vdf
{
bool operator==(const tyti::vdf::object &rhs, const tyti::vdf::object &lhs)
template <typename charT>
bool equal_impl(const tyti::vdf::basic_object<charT> &rhs,
const tyti::vdf::basic_object<charT> &lhs)
{
if (rhs.name != lhs.name)
return false;
Expand Down Expand Up @@ -33,6 +33,20 @@ bool operator==(const tyti::vdf::object &rhs, const tyti::vdf::object &lhs)

return true;
}

namespace tyti::vdf
{

bool operator==(const tyti::vdf::wobject &rhs, const tyti::vdf::wobject &lhs)
{
return equal_impl(rhs, lhs);
}

bool operator==(const tyti::vdf::object &rhs, const tyti::vdf::object &lhs)
{
return equal_impl(rhs, lhs);
}

} // namespace tyti::vdf

namespace rc::details
Expand Down
15 changes: 12 additions & 3 deletions tests/proptests/generators/vdf_object_generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
namespace tyti::vdf
{
bool operator==(const tyti::vdf::object &rhs, const tyti::vdf::object &lhs);
bool operator==(const tyti::vdf::wobject &rhs, const tyti::vdf::wobject &lhs);

} // namespace tyti::vdf

Expand All @@ -15,9 +16,17 @@ template <> struct Arbitrary<tyti::vdf::object>
{
static Gen<tyti::vdf::object> arbitrary()
{
using tyti::vdf::object;
return gen::build<object>(gen::set(&object::name),
gen::set(&object::attribs));
using obj = tyti::vdf::object;
return gen::build<obj>(gen::set(&obj::name), gen::set(&obj::attribs));
}
};

template <> struct Arbitrary<tyti::vdf::wobject>
{
static Gen<tyti::vdf::wobject> arbitrary()
{
using obj = tyti::vdf::wobject;
return gen::build<obj>(gen::set(&obj::name), gen::set(&obj::attribs));
}
};
} // namespace rc
Expand Down
197 changes: 106 additions & 91 deletions tests/proptests/main_rapidcheck.cpp
Original file line number Diff line number Diff line change
@@ -1,154 +1,169 @@
#define TYTI_NO_L_UNDEF
#include <vdf_parser.hpp>
#define T_L(x) TYTI_L(charT, x)

#include "generators/vdf_multiobject_generator.hpp"
#include "generators/vdf_object_generator.hpp"
#include <algorithm>
#include <string>
#include <vdf_parser.hpp>

bool containsSurrogate(const std::wstring &str)
{
return str.find(wchar_t(-1)) != str.npos;
}

int main()
////////////////////////////////////////////////////////////////
template <typename charT> std::basic_string<charT> genValidNameString();

template <> std::string genValidNameString<char>()
{
return *rc::gen::string<std::string>();
}

////////////////////////////////////////////////////////////////
// object parsing tests
template <> std::wstring genValidNameString<wchar_t>()
{
return *rc::gen::suchThat(rc::gen::string<std::wstring>(),
[](const auto &str)
{ return !containsSurrogate(str); });
}

using namespace tyti;
bool success = true;
success &= rc::check(
"serializing and then parsing just the name with default options "
"should return the original name",
[]()
{
vdf::object obj;
obj.name = *rc::gen::string<std::string>();
////////////////////////////////////////////////////////////////
template <typename charT>
std::basic_string<charT> genValidUnescapedNameString();

std::stringstream sstr;
vdf::write(sstr, obj);
template <> std::string genValidUnescapedNameString<char>()
{
return *rc::gen::suchThat(rc::gen::string<std::string>(),
[](const std::string &str)
{ return str.find("\"") == str.npos; });
}

auto to_test = vdf::read(sstr);
RC_ASSERT(obj.name == to_test.name);
});
template <> std::wstring genValidUnescapedNameString<wchar_t>()
{
return *rc::gen::suchThat(
rc::gen::string<std::wstring>(), [](const std::wstring &str)
{ return str.find(L"\"") == str.npos && !containsSurrogate(str); });
}

success &= rc::check(
"serializing and then parsing just the name with default options "
"should return the original name - not escaped",
[]()
{
vdf::object obj;
obj.name = *rc::gen::suchThat(rc::gen::string<std::string>(),
[](const std::string &str) {
return str.find("\"") == str.npos;
});
////////////////////////////////////////////////////////////////
template <typename T> const char *getName();

vdf::WriteOptions writeOpts;
writeOpts.escape_symbols = false;
template <> const char *getName<tyti::vdf::multikey_object>()
{
return "multikey_object";
}
template <> const char *getName<tyti::vdf::wmultikey_object>()
{
return "wmultikey_object";
}

vdf::Options readOpts;
readOpts.strip_escape_symbols = false;
template <> const char *getName<tyti::vdf::object>() { return "object"; }
template <> const char *getName<tyti::vdf::wobject>() { return "wobject"; }

std::stringstream sstr;
vdf::write(sstr, obj, writeOpts);
template <> const char *getName<char>() { return "char"; }

auto to_test = vdf::read(sstr, readOpts);
RC_ASSERT(obj.name == to_test.name);
});
template <> const char *getName<wchar_t>() { return "wchar_t"; }
////////////////////////////////////////////////////////////////

template <typename charT, template <typename T> typename basic_obj>
bool executeTest(std::string_view test_name, auto test_f)
{
using obj = basic_obj<charT>;
auto f = [test_f = std::move(test_f)]()
{ test_f.template operator()<charT, obj>(); };

success &= rc::check(
return rc::check(std::format("{} - {} - {}", std::string{test_name},
getName<charT>(), getName<obj>()),
f);
}

bool forAllObjectPermutations(std::string_view test_name, auto test_f)
{
using namespace tyti;
bool ret = false;
ret &= executeTest<char, vdf::basic_object>(test_name, std::move(test_f));
ret &=
executeTest<wchar_t, vdf::basic_object>(test_name, std::move(test_f));
ret &= executeTest<char, vdf::basic_multikey_object>(test_name,
std::move(test_f));
ret &= executeTest<wchar_t, vdf::basic_multikey_object>(test_name,
std::move(test_f));
return ret;
}

int main()
{

////////////////////////////////////////////////////////////////
// object parsing tests
using namespace tyti;
bool success = true;

success &= forAllObjectPermutations(
"serializing and then parsing just the name with default options "
"should return the original name - wchar_t",
[]()
"should return the original name",
[]<typename charT, typename objType>()
{
vdf::wobject obj;
obj.name = *rc::gen::suchThat(rc::gen::string<std::wstring>(),
[](const auto &str)
{ return !containsSurrogate(str); });
objType obj;
obj.name = genValidNameString<charT>();

std::wstringstream sstr;
std::basic_stringstream<charT> sstr;
vdf::write(sstr, obj);

auto to_test = vdf::read(sstr);
auto to_test = vdf::read<objType>(sstr);
RC_ASSERT(obj.name == to_test.name);
});

success &= rc::check(
success &= forAllObjectPermutations(
"serializing and then parsing just the name with default options "
"should return the original name - not escaped - wchar_t",
[]()
"should return the original name - not escaped",
[]<typename charT, typename objType>()
{
vdf::wobject obj;
obj.name =
*rc::gen::suchThat(rc::gen::string<std::wstring>(),
[](const std::wstring &str) {
return str.find(L"\"") == str.npos &&
!containsSurrogate(str);
});
objType obj;
obj.name = genValidUnescapedNameString<charT>();

vdf::WriteOptions writeOpts;
writeOpts.escape_symbols = false;

vdf::Options readOpts;
readOpts.strip_escape_symbols = false;

std::wstringstream sstr;
std::basic_stringstream<charT> sstr;
vdf::write(sstr, obj, writeOpts);

auto to_test = vdf::read(sstr, readOpts);
auto to_test = vdf::read<objType>(sstr, readOpts);
RC_ASSERT(obj.name == to_test.name);
});

success &= rc::check(
success &= forAllObjectPermutations(
"check if the attributes are also written and parsed correctly",
[](const vdf::object &in)
[]<typename charT, typename objType>()
{
std::stringstream sstr;
objType in = *rc::gen::arbitrary<objType>();
std::basic_stringstream<charT> sstr;
vdf::write(sstr, in);
auto to_test = tyti::vdf::read(sstr);
auto to_test = tyti::vdf::read<objType>(sstr);
RC_ASSERT(in == to_test);
});

success &= rc::check(
success &= forAllObjectPermutations(
"check if the childs are also written and parsed correctly",
[](vdf::object in)
{
// todo this just tests childs with depth 1
using child_vec = std::vector<std::shared_ptr<vdf::object>>;
child_vec childs =
*rc::gen::container<child_vec>(rc::gen::makeShared<vdf::object>(
rc::gen::arbitrary<vdf::object>()));

for (const auto &c : childs)
{
in.childs.emplace(c->name, c);
}

std::stringstream sstr;
vdf::write(sstr, in);
auto to_test = tyti::vdf::read(sstr);
RC_ASSERT(in == to_test);
});

success &= rc::check(
"check if the childs are also written and parsed correctly - multikey",
[](vdf::multikey_object in)
[]<typename charT, typename objType>()
{
objType in = *rc::gen::arbitrary<objType>();
// todo this just tests childs with depth 1
using child_vec =
std::vector<std::shared_ptr<vdf::multikey_object>>;
using child_vec = std::vector<std::shared_ptr<objType>>;
child_vec childs = *rc::gen::container<child_vec>(
rc::gen::makeShared<vdf::multikey_object>(
rc::gen::arbitrary<vdf::multikey_object>()));
rc::gen::makeShared<objType>(rc::gen::arbitrary<objType>()));

for (const auto &c : childs)
{
in.childs.emplace(c->name, c);
}

std::stringstream sstr;
std::basic_stringstream<charT> sstr;
vdf::write(sstr, in);
auto to_test = tyti::vdf::read<vdf::multikey_object>(sstr);
auto to_test = tyti::vdf::read<objType>(sstr);
RC_ASSERT(in == to_test);
});

Expand Down

0 comments on commit 8399b59

Please sign in to comment.