BaseClassInfo

ClassName

ClassName

ClassName

Test

TestBase

TestInheritance

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
// -*- C++ -*-
//
// Package:     CondFormats/SerializationHelper
// Class  :     test_catch2_SerializationHelper
//
// Implementation:
//     [Notes on implementation]
//
// Original Author:  Christopher Jones
//         Created:  Wed, 31 May 2023 19:12:55 GMT
//

// system include files
#include "catch.hpp"

// user include files
#include "CondFormats/SerializationHelper/interface/SerializationHelper.h"

namespace {
  struct Test {
    Test() = default;
    Test(float iA, int iB) : a_{iA}, b_{iB} {}

    float a_;
    int b_;

    template <class Archive>
    void serialize(Archive& ar, const unsigned int version) {
      ar & a_;
      ar & b_;
      ++counter_;
    }

    int counter_ = 0;
  };

  struct TestBase {
    virtual ~TestBase() noexcept {}

    virtual int value() const = 0;

    template <class Archive>
    void serialize(Archive& ar, const unsigned int version) {}
  };

  struct TestInheritance : public TestBase {
    ~TestInheritance() noexcept override = default;

    int value() const final { return value_; }

    template <class Archive>
    void serialize(Archive& ar, const unsigned int version) {
      ar & value_;
    }
    int value_ = 3145;
  };

}  // namespace

namespace cond::serialization {
  template <>
  struct ClassName<Test> {
    constexpr static std::string_view kName = "Test";
  };
  template <>
  struct ClassName<TestBase> {
    [[maybe_unused]] constexpr static std::string_view kName = "TestBase";
  };
  template <>
  struct ClassName<TestInheritance> {
    constexpr static std::string_view kName = "TestInheritance";
  };

  template <>
  struct BaseClassInfo<TestBase> : public BaseClassInfoImpl<TestBase, true, TestInheritance> {};
}  // namespace cond::serialization

using namespace cond::serialization;

TEST_CASE("Test SerializationHelper", "[SerializationHelper]") {
  SECTION("serialize") {
    SerializationHelper<Test> helper;

    std::stringbuf dataBuffer;

    Test test{1.3, -4};
    REQUIRE(test.counter_ == 0);

    auto typeName = helper.serialize(dataBuffer, &test);

    REQUIRE(dataBuffer.str().size() > 0);
    REQUIRE(test.counter_ == 1);
    REQUIRE(typeName == "Test");
  }

  SECTION("deserialize") {
    SerializationHelper<Test> helper;

    std::stringbuf dataBuffer;
    std::string_view typeName;
    {
      Test test{1.3, -4};
      REQUIRE(test.counter_ == 0);

      typeName = helper.serialize(dataBuffer, &test);
    }

    auto voidPtr = helper.deserialize(dataBuffer, typeName);

    const Test* pTest = static_cast<const Test*>(voidPtr.get());
    REQUIRE_THAT(pTest->a_, Catch::Matchers::WithinAbs(1.3, 0.001));
    REQUIRE(pTest->b_ == -4);
    REQUIRE(pTest->counter_ == 1);
  }

  SECTION("polymorphic serialize") {
    SerializationHelper<TestBase> helper;

    std::stringbuf dataBuffer;

    TestInheritance test{};

    auto typeName = helper.serialize(dataBuffer, &test);

    REQUIRE(typeName == "TestInheritance");
    REQUIRE(dataBuffer.str().size() > 0);
    REQUIRE(test.value() == 3145);
  }

  SECTION("deserialize") {
    SerializationHelper<TestBase> helper;

    std::stringbuf dataBuffer;
    std::string_view typeName;
    {
      TestInheritance test;

      typeName = helper.serialize(dataBuffer, &test);
    }

    auto voidPtr = helper.deserialize(dataBuffer, typeName);
    REQUIRE(voidPtr.get() != nullptr);

    const TestBase* pTest = static_cast<const TestBase*>(voidPtr.get());
    REQUIRE(pTest->value() == 3145);
  }
}