[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/ModuleWorks/taskflow/task_isolation/unittests/test_serializer.cpp [Back]  [Original]

#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN

#include 
#include 
#include 

// ----------------------------------------------------------------------------
// Random generator utilities
// ----------------------------------------------------------------------------

// Function: random_engine
inline std::default_random_engine& random_engine() {
  thread_local std::default_random_engine gen{0};
  return gen;
}

// Function: random
// Randomly generate a floating value in the given range.
template 
std::enable_if_t random(
  const T from = -1.0,
  const T to = 1.0
) {
  return std::uniform_real_distribution(from, to)(random_engine());
}

// Function: random
// Randomly generate an integer value.
template 
std::enable_if_t random(
  const T from = std::numeric_limits::lowest(),
  const T to = std::numeric_limits::max()
) {
  return std::uniform_int_distribution(from, to)(random_engine());
}

// Function: random
// Randomly generate a string.
template 
std::enable_if_t random(
  const std::string::value_type from = ' ',
  const std::string::value_type to = '~',
  const std::string::size_type len = 16
) {
  std::string str(len, ' ');
  for(auto& c : str) {
    c = random(from, to) % 128;
  }
  return str;
}

// ----------------------------------------------------------------------------

// Struct: PODs
struct PODs {

  unsigned      pod_uint32 = random();
  int           pod_int32  = random();
  unsigned long long pod_uint64 = random();
  long long     pod_int64  = random();
  float_t       pod_float  = random();
  double_t      pod_double = random();

  template 
  auto save( ArchiverT& ar ) const {
    return ar(
      pod_uint32,
      pod_int32,
      pod_uint64,
      pod_int64,
      pod_float,
      pod_double
    );
  }

  template 
  auto load( ArchiverT& ar ) {
    return ar(
      pod_uint32,
      pod_int32,
      pod_uint64,
      pod_int64,
      pod_float,
      pod_double
    );
  }

  bool operator == (const PODs& rhs) const {
    return pod_uint32 == rhs.pod_uint32 &&
           pod_int32  == rhs.pod_int32  &&
           pod_uint64 == rhs.pod_uint64 &&
           pod_int64  == rhs.pod_int64  &&
           pod_float  == rhs.pod_float  &&
           pod_double == rhs.pod_double;
  }

  bool operator != (const PODs& rhs) const {
    return !(*this == rhs);
  }
};

// Procedure: test_pod
// The templated procedure for testing POD. Caller must specify the output
// and input archiver type.
void test_pod() {

  // Output stream.
  std::ostringstream os;
  tf::Serializer oar(os);

  const auto o_uint32 = random();
  const auto o_int32  = random();
  const auto o_uint64 = random();
  const auto o_int64  = random();
  const auto o_float  = random();
  const auto o_double = random();

  auto o_sz = oar(
    o_uint32,
    o_int32,
    o_uint64,
    o_int64,
    o_float,
    o_double
  );

  //REQUIRE(o_sz == os.out_avail());

  // InputStreamBuffer
  std::istringstream is(os.str());
  tf::Deserializer iar(is);

  auto i_uint32 = random();
  auto i_int32  = random();
  auto i_uint64 = random();
  auto i_int64  = random();
  auto i_float  = random();
  auto i_double = random();

  auto i_sz = iar(
    i_uint32,
    i_int32,
    i_uint64,
    i_int64,
    i_float,
    i_double
  );
  REQUIRE(is.rdbuf()->in_avail() == 0);

  REQUIRE(i_sz == o_sz);
  REQUIRE(o_uint32 == i_uint32);
  REQUIRE(o_int32 == i_int32);
  REQUIRE(o_uint64 == i_uint64);
  REQUIRE(o_int64 == i_int64);
  REQUIRE(o_float == i_float);
  REQUIRE(o_double == i_double);
}

// Procedure: test_struct
// The templated procedure for testing POD. Caller must specify the output
// and input archiver type.
void test_struct() {

  for(size_t i=0; iin_avail() == 0);

    REQUIRE(o_sz == i_sz);
    REQUIRE(o_pods == i_pods);
  }
}

// Procedure: test_string
// Template for testing basic strings. Caller must specify the output and input archiver type.
template 
void test_string() {

  for(size_t i=0; iin_avail() == 0);

    REQUIRE(o_sz == i_sz);
    REQUIRE(o_char_str == i_char_str);
  }
}

#define TEST_SEQ_CONT_BODY(container)                          \
                                                               \
for(size_t i=0; iin_avail());                                          \
                                                                                 \
  REQUIRE(o_sz == i_sz);                                                         \
  REQUIRE(o_int32s == i_int32s);                                                 \
  REQUIRE(o_int64s == i_int64s);                                                 \
  REQUIRE(o_chars == i_chars);                                                   \
  REQUIRE(o_floats == i_floats);                                                 \
  REQUIRE(o_doubles == i_doubles);                                               \
  REQUIRE(o_strings == i_strings);                                               \
}


#define TEST_SET_CONT_BODY(container)                                           \
                                                                                \
for (size_t i = 0; i < 64; i++) {                                             \
  const size_t num_data = random(1, 1024);                              \
  std::ostringstream os;                                                        \
  tf::Serializer oar(os);                                             \
                                                                                \
  std::container o_int32s;                                             \
  std::container o_int64s;                                             \
  std::container o_chars;                                                 \
  std::container o_floats;                                               \
  std::container o_doubles;                                             \
  std::container o_strings;                                        \
                                                                                \
  for (size_t j = 0; j < num_data; j++) {                                       \
    o_int32s.emplace(random());                                        \
    o_int64s.emplace(random());                                        \
    o_chars.emplace(random());                                            \
    o_floats.emplace(random());                                        \
    o_doubles.emplace(random());                                      \
    o_strings.emplace(random());                                   \
  }                                                                             \
  auto o_sz = oar(o_int32s, o_int64s, o_chars, o_floats, o_doubles, o_strings); \
                                                                                \
  std::istringstream is(os.str());                                              \
  tf::Deserializer iar(is);                                             \
                                                                                \
  std::container i_int32s;                                             \
  std::container i_int64s;                                             \
  std::container i_chars;                                                 \
  std::container i_floats;                                               \
  std::container i_doubles;                                             \
  std::container i_strings;                                        \
                                                                                \
  auto i_sz = iar(i_int32s, i_int64s, i_chars, i_floats, i_doubles, i_strings); \
  REQUIRE(0 == is.rdbuf()->in_avail());                                         \
                                                                                \
  REQUIRE(o_sz == i_sz);                                                        \
  REQUIRE(o_int32s == i_int32s);                                                \
  REQUIRE(o_int64s == i_int64s);                                                \
  REQUIRE(o_chars == i_chars);                                                  \
  REQUIRE(o_floats == i_floats);                                                \
  REQUIRE(o_doubles == i_doubles);                                              \
  REQUIRE(o_strings == i_strings);                                              \
}

// Procedure: test_array
// Template procedure for testing array container.
void test_array() {

  for(size_t i=0; iin_avail());

    REQUIRE(osz == isz);
    REQUIRE(ochar == ichar);
    REQUIRE(oint == iint);
    REQUIRE(odouble == idouble);
    REQUIRE(ostring == istring);
  }
}

// Procedure: test_variant
void test_variant() {

  for (size_t i = 0; i < 64; i++) {

    // Single POD variant.
    std::variant opod1 = random();
    std::variant ipod1 = random();

    // Multiple POD variant
    std::variant opod2 = random();
    std::variant ipod2 = random();

    // Multiple POD variant
    std::variant opod3 = random()%2;
    std::variant ipod3 = random();

    // Mixing float and string
    std::variant omix2 = random();
    std::variant imix2 = random();

    // Recursive variant
    std::variant orec2 = omix2;
    std::variant irec2 = random();

    // Output archiver
    std::ostringstream os;
    tf::Serializer oar(os);
    auto osz = oar(opod1, opod2, opod3, omix2, orec2);

    // Input archiver
    std::istringstream is(os.str());
    tf::Deserializer iar(is);
    auto isz = iar(ipod1, ipod2, ipod3, imix2, irec2);
    REQUIRE(0 == is.rdbuf()->in_avail());

    REQUIRE(osz == isz);
    REQUIRE(opod1 == ipod1);
    REQUIRE(opod2 == ipod2);
    REQUIRE(opod3 == ipod3);
    REQUIRE(omix2 == imix2);
    REQUIRE(orec2 == irec2);
  }
}

// Procedure: test_time_point
void test_time_point() {

  for(auto i=0; iin_avail());
    REQUIRE(osz == isz);

    REQUIRE(o_tpt1 == i_tpt1);
    REQUIRE(o_tpt2 == i_tpt2);
    REQUIRE(o_tpt3 == i_tpt3);
    REQUIRE(o_dur1 == i_dur1);
    REQUIRE(o_dur2 == i_dur2);
    REQUIRE(o_dur3 == i_dur3);
  }
}

// Procedure: test_optional
void test_optional() {

  for(auto i=0; iin_avail());
    REQUIRE(osz == isz);

    REQUIRE(o_nbool == i_nbool);
    REQUIRE(o_ybool == i_ybool);
    REQUIRE(o_nstr == i_nstr);
    REQUIRE(o_ystr == i_ystr);
  }
}

// Procedure: test_tuple
void test_tuple() {

  for(auto i=0; iin_avail());
    REQUIRE(osz == isz);

    REQUIRE(o0 == i0);
    REQUIRE(o1 == i1);
    REQUIRE(o2 == i2);
    REQUIRE(o3 == i3);
    REQUIRE(o4 == i4);
  }
}

// ----------------------------------------------------------------------------

// POD
TEST_CASE("POD" * doctest::timeout(300)) {
  test_pod();
}

// POD-struct
TEST_CASE("POD-Struct" * doctest::timeout(300)) {
  test_struct();
}

// std::string
TEST_CASE("string" * doctest::timeout(300)) {
  test_string();
}

// std::vector
TEST_CASE("vector" * doctest::timeout(300)) {
  TEST_SEQ_CONT_BODY(vector)
}

// std::deque
TEST_CASE("deque" * doctest::timeout(300)) {
  TEST_SEQ_CONT_BODY(deque)
}

// std::list
TEST_CASE("list" * doctest::timeout(300)) {
  TEST_SEQ_CONT_BODY(list)
}

// std::forward_list
TEST_CASE("forward_list" * doctest::timeout(300)) {
  TEST_SEQ_CONT_BODY(forward_list)
}

// std::map
TEST_CASE("map" * doctest::timeout(300)) {
  TEST_MAP_CONT_BODY(map);
}

// std::unordered_map
TEST_CASE("unordered_map" * doctest::timeout(300)) {
  TEST_MAP_CONT_BODY(unordered_map);
}

// std::set
TEST_CASE("set" * doctest::timeout(300)) {
  TEST_SET_CONT_BODY(set);
}

// std::unordered_set
TEST_CASE("unordered_set" * doctest::timeout(300)) {
  TEST_SET_CONT_BODY(unordered_set);
}

// std::array
TEST_CASE("array" * doctest::timeout(300)) {
  test_array();
}

// std::chrono::time_point
TEST_CASE("time_point" * doctest::timeout(300)) {
  test_time_point();
}

// std::optional
TEST_CASE("optional" * doctest::timeout(300)) {
  test_optional();
}

// std::tuple
TEST_CASE("tuple" * doctest::timeout(300)) {
  test_tuple();
}

Web Proxy Viewer  |  New URL  |  Original Page